27. 좌표·각도 양자화(quantization) 직렬화의 경계 처리 결함 (C#)

난이도 하 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// ─────────────────────────────────────────────────────────────
// 시나리오: 대역폭 절약을 위해 이동 패킷의 위치(x,y,z)와 바라보는 각도를
//   float 그대로 보내지 않고 16비트 정수로 양자화(quantize)해 전송한다.
//   수신 측은 역양자화(dequantize)해 월드 좌표/각도로 복원한다.
//   월드는 [0, WorldSize] 정육면체이고, 각도는 라디안이다.
//
//   클라가 보내는 좌표는 넉백/추락/스킬 이동/부동소수 오차 등으로
//   가끔 월드 경계를 살짝 벗어나거나 음수가 될 수 있고, 각도는 누적 회전으로
//   2π를 넘거나 음수가 될 수 있다(정규화 전 값).
//
// 요구사항:
//   - 양자화→역양자화 왕복 후 좌표/각도가 "원래 값에 가깝게" 복원되어야 하고,
//     특히 범위를 벗어난 입력이 들어와도 엉뚱한 위치로 튀면 안 된다.
//
// 과제: (A)(B) 지점을 검토하라. 경계를 벗어난 입력(예: x = -0.5, x = WorldSize+3,
//        angle = -0.1, angle = 7.0)이 들어올 때 복원 결과가 어떻게 되는지
//        구체적으로 설명하고, 수정안을 제시하라.
// ─────────────────────────────────────────────────────────────
using System;

namespace Net
{
    public struct QuantPos { public ushort X, Y, Z; }

    public static class Quantizer
    {
        public const float WorldSize = 4096.0f;
        private const float TwoPi = (float)(2 * Math.PI);

        public static QuantPos QuantizePos(float x, float y, float z)
        {
            QuantPos q;
            // (A)
            q.X = (ushort)(x / WorldSize * 65535.0f);
            q.Y = (ushort)(y / WorldSize * 65535.0f);
            q.Z = (ushort)(z / WorldSize * 65535.0f);
            return q;
        }

        public static (float x, float y, float z) DequantizePos(QuantPos q)
        {
            return (q.X / 65535.0f * WorldSize,
                    q.Y / 65535.0f * WorldSize,
                    q.Z / 65535.0f * WorldSize);
        }

        public static ushort QuantizeAngle(float radians)
        {
            // (B)
            return (ushort)(radians / TwoPi * 65535.0f);
        }

        public static float DequantizeAngle(ushort q) => q / 65535.0f * TwoPi;
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.