C#/디딤돌 C#

[C#] 2. 기본 형식 II - 다양한 정수 형식, 실수 형식

언휴 2024. 1. 22. 10:49

2.4 다양한 정수 형식

C#은 다양한 정수 형식을 제공합니다. 

 1바이트인 sbyte, byte2바이트인 short, ushort, 4바이트인 int, uint, 8바이트인 long, ulong을 제공합니다. 

 정수 형식에는 정적 멤버로 MinValueMaxValue 속성을 제공합니다. 이를 통해 표현 범위를 알아봅시다.

using System;

namespace _03.정수_형식
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("sbyte:{0} ~ {1}", sbyte.MinValue, sbyte.MaxValue);
            Console.WriteLine("byte:{0} ~ {1}", byte.MinValue, byte.MaxValue);
            Console.WriteLine("short:{0} ~ {1}", short.MinValue, short.MaxValue);
            Console.WriteLine("ushort:{0} ~ {1}", ushort.MinValue, ushort.MaxValue);
            Console.WriteLine("int:{0} ~ {1}", int.MinValue, int.MaxValue);
            Console.WriteLine("uint:{0} ~ {1}", uint.MinValue, uint.MaxValue);
            Console.WriteLine("long:{0} ~ {1}", long.MinValue, long.MaxValue);
            Console.WriteLine("ulong:{0} ~ {1}", ulong.MinValue, ulong.MaxValue);

        }
    }
}

▶ 실행 결과

sbyte:-128 ~ 127
byte:0 ~ 255
short:-32768 ~ 32767
ushort:0 ~ 65535
int:-2147483648 ~ 2147483647
uint:0 ~ 4294967295
long:-9223372036854775808 ~ 9223372036854775807
ulong:0 ~ 18446744073709551615

2.5 실수 형식 (부동 소수점 형식)

C#은 실수 형식으로 float, double, decimal을 제공합니다. 실수 형식을 부동 소수점 형식으로 부릅니다. 

 C#에서는 System.Singlefloat, System.Doubledouble, System.Decimaldecimal로 부르는 것입니다. 

 프로그램에서 실수는 0에서 1사이에도 무한 개가 있어서 정확한 표현이 아닌 근사 범위를 갖는 근사치 표현입니다. C#에서 제공하는 3가지 실수 형식은 메모리 크기, 표현 범위 뿐만 아니라 근사 범위도 다릅니다.

[표 2.3] 실수 형식의 근사 범위
[표 2.3] 실수 형식의 근사 범위

 실수 형식에도 정적 멤버 MinValueMaxValue를 제공합니다.

using System;

namespace _04_실수_형식_표현_범위
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("float:{0} ~ {1}", float.MinValue, float.MaxValue);
            Console.WriteLine("double:{0} ~ {1}", double.MinValue, double.MaxValue);
            Console.WriteLine("decimal:{0} ~ {1}", decimal.MinValue, decimal.MaxValue);   
        }
    }
}

▶ 실행 결과

float:-3.402823E+38 ~ 3.402823E+38
double:-1.79769313486232E+308 ~ 1.79769313486232E+308
decimal:-79228162514264337593543950335 ~ 79228162514264337593543950335

 floatdouble2진수 체계로 실수를 표현합니다. 

 floatdouble 형식 10진수 0.1을 정확히 표현할 수 없습니다. 이는 2진수 체계로 표현하기 때문입니다. 10진수 0.12진수로 표현하면 0.00110011001100... 입니다. 

 반면 decimal은 형식 이름을 보면 알 수 있듯이 10진수 계산에 유리하게 설계하였습니다. 

 다음은 float, double, decimal 형식 변수를 0으로 초기화한 후 0.110번 더했을 때 결과가 1과 같은지 비교하는 코드입니다.

using System;

namespace 실수_표현의_오차
{
    internal class Program
    {
        static void Main(string[] args)
        {
            float f = 0.0f;
            double d = 0.0;
            decimal de = 0.0m;

            for(int i = 0; i<10;i++)
            {
                f += 0.1f;
                d += 0.1;
                de += 0.1m;
            }
            Console.WriteLine(f == 1.0f);
            Console.WriteLine(d == 1.0);
            Console.WriteLine(de == 1.0m);
        }
    }
}

▶ 실행 결과

False
False
True

 결과를 보면 알 수 있듯이 float 형식과 double 형식은 0.110번 더했을 때 결과가 1.0과 다르다고 하네요. 반면 decimal1.0과 같다고 나왔습니다. 

 이러한 결과가 나오는 이유를 알려면 float, double 형식 값을 메모리에 표현하는 방법을 알아야합니다. 

 float4바이트 실수 표현 규약인 IEEE754를 따르며 부호(1 비트), 지수 (8 비트), 가수 (23 비트)로 구성합니다. (언제나 휴일 유튜브에 4이트 리에 을 알려주세요. 동영상을 참고하세요.) double은 부호(1비트), 지수(11 비트), 가수(52 비트)로 구성합니다. 

 decimal10진수 체계로 메모리에 표현하고 있습니다. 여기에서는 실수 형식은 근사 범위를 갖는 것과 10진수 계산에서는 decimal 형식을 사용하는 것이 정확할 수 있다는 것을 소개하는 정도로 할게요. 

 이 외에 stringobject도 기본 형식입니다. 

 문자열 형식인 string과 모든 형식의 기반인 object는 뒤에서 별도로 다루기로 할게요.