소프트웨어 gcc에서 long double형과 double형 차이 알아보기?
2020.02.11 05:02
#include <stdio.h>
int main(void)
{
int t;
long double a;
double b;
for (t=27; t<45; t++)
{
a = ((t-1350.0L)/83.0L)*((t-1350.0L)/83.0L);
printf(" ((%d-1350)/83)*((%d-1350)/83) = %25.20Lf\n", t, t, a);
b = ((t-1350.0)/83.0)*((t-1350.0)/83.0);
printf(" ((%d-1350)/83)*((%d-1350)/83) = %25.20f\n", t, t, b);
}
}
위의 프로그램을 컴파일하여 실행하면 아래와 같이 결과가 같은데 왜 그럴까요? long double형이 좀더 정확하게 출력되지 않네요?
choe@DESKTOP-KOP92G2:~$ gcc test5.c
choe@DESKTOP-KOP92G2:~$ ./a.out
((27-1350)/83)*((27-1350)/83) = 254.07591813035270433829
((27-1350)/83)*((27-1350)/83) = 254.07591813035270433829
((28-1350)/83)*((28-1350)/83) = 253.69197271011759653447
((28-1350)/83)*((28-1350)/83) = 253.69197271011759653447
((29-1350)/83)*((29-1350)/83) = 253.30831760778053762806
((29-1350)/83)*((29-1350)/83) = 253.30831760778053762806
((30-1350)/83)*((30-1350)/83) = 252.92495282334158446247
((30-1350)/83)*((30-1350)/83) = 252.92495282334158446247
((31-1350)/83)*((31-1350)/83) = 252.54187835680070861599
((31-1350)/83)*((31-1350)/83) = 252.54187835680070861599
((32-1350)/83)*((32-1350)/83) = 252.15909420815793851034
((32-1350)/83)*((32-1350)/83) = 252.15909420815793851034
((33-1350)/83)*((33-1350)/83) = 251.77660037741327414551
((33-1350)/83)*((33-1350)/83) = 251.77660037741327414551
((34-1350)/83)*((34-1350)/83) = 251.39439686456668709980
((34-1350)/83)*((34-1350)/83) = 251.39439686456668709980
((35-1350)/83)*((35-1350)/83) = 251.01248366961823421661
((35-1350)/83)*((35-1350)/83) = 251.01248366961823421661
((36-1350)/83)*((36-1350)/83) = 250.63086079256785865255
((36-1350)/83)*((36-1350)/83) = 250.63086079256785865255
((37-1350)/83)*((37-1350)/83) = 250.24952823341558882930
((37-1350)/83)*((37-1350)/83) = 250.24952823341558882930
((38-1350)/83)*((38-1350)/83) = 249.86848599216139632517
((38-1350)/83)*((38-1350)/83) = 249.86848599216139632517
((39-1350)/83)*((39-1350)/83) = 249.48773406880530956187
((39-1350)/83)*((39-1350)/83) = 249.48773406880530956187
((40-1350)/83)*((40-1350)/83) = 249.10727246334738538280
((40-1350)/83)*((40-1350)/83) = 249.10727246334738538280
((41-1350)/83)*((41-1350)/83) = 248.72710117578751010115
((41-1350)/83)*((41-1350)/83) = 248.72710117578751010115
((42-1350)/83)*((42-1350)/83) = 248.34722020612571213860
((42-1350)/83)*((42-1350)/83) = 248.34722020612571213860
((43-1350)/83)*((43-1350)/83) = 247.96762955436204833859
((43-1350)/83)*((43-1350)/83) = 247.96762955436204833859
((44-1350)/83)*((44-1350)/83) = 247.58832922049646185769
((44-1350)/83)*((44-1350)/83) = 247.58832922049646185769
choe@DESKTOP-KOP92G2:~$
댓글 [6]
-
익덕이 2020.02.11 13:02
-
나는나다 2020.02.11 14:07
gcc에서 long double형이 좀더 정밀도가 높습니다. 예를 들어 아래 프로그램 출력 결과는 long double형이 double형보다 좀더 정확하게 출력됩니다
#include <math.h>
#include <stdio.h>extern int main(){
const char *pi="3.14159265358979323846";
long double lpi;
double dpi;
float fpi;lpi = 4.0*atanl(1.0L);
dpi = 4.0*atan(1.0);
fpi = 4.0*atanf((float)1.0);
printf(" 12345678901234567890\n");
printf("pi = %25s\n", pi);
printf("lpi = %25.20Lf\n", lpi);
printf("dpi = %25.20f\n", dpi);
printf("fpi = %25.20f\n\n", fpi);}
-
메리아 2020.02.11 14:06
#include <stdio.h>
int main(void) {
// your code goes here
printf("%d\n",sizeof(double));
printf("%d\n",sizeof(long double));
return 0;
}
이걸 https://ideone.com 에서 해보면각각 8, 16이 나옵니다.리눅스쪽에서는 잘 안해봐서 long double 크기가 어떤지 모르겠으나double은 일단 어디서나 기본 8바이트입니다. 아마 ideone.com도 리눅스 베이스일테니 long double도 16바이트 맞을겁니다.그리고 정확하지 않다는게 뭘 보고 하시는 말씀인지 모르겠네요.출력 보면 차이를 잘 모르겠는데요.그리고 IEEE 754 부동 소수점 규약에 의해어차피 정밀도는 100%가 안나올뿐더러, 바이트 크기가 클수록 좀 더 근사치에 가깝습니다.다만 명시하지 않을경우 double이 계산의 기본이 되는 예가 있습니다.그래서 long double은 double과 정밀도가 같거나 더 높아야 정상입니다.단, decimal 종류의 경우 부동소수점이 아닌 정수와 같은 방식의 계산법을 쓰는데요
이는 정밀도가 그냥 정수 그 자체라서 오차가 생기지 않습니다.
문제는 기껏 decimal로 정의해놓고는 위에 말했듯 double 기본계산으로 넘어가버리는 예가 종종 있어서
매 계산시마다 decimal casting이 분명한지 확인해야합니다.
-
나는나다 2020.02.11 14:11
정확하다는 의미는 참값으로 출력되는 유효자리수의 개수가 더 많다는 의미로 말했던 것이었습니다. gcc에서 long double형의 정밀도가 double형보다 높은데 위의 경우에는 왜 두 자료형이 차이가 없는지 모르겠네요
-
메리아 2020.02.11 15:29
뭔가 님 리눅스 설정이 이상하지 않나 싶긴 하네요.
본문 그대로 복붙해서
저기서 돌려보면 유효숫자 15자리 쯤에서 분명한 차이가 생기는데...
sizeof 로 바이트 크기 한번 확인하시고
제가 궁금한건 "더 정확하다"는 근거가 뭐였는지 궁금하네요.
애초에 저런 숫자면 정확도 구분이 안될텐데요?
어느게 맞는지 알수가 없는데...
"참값"이라는거 자체가 사실상 없습니다.
다 근사값이고 굳이 참값을 원하면 유효자릿수 내에서
decimal 계열 고정소수점을 이용하는거 밖에는요,
-
나는나다 2020.02.11 19:37
어라, 신기하네요. 말씀하신 사이트에서는 정말 다르네요. gcc 버전 차이는 아닌 것 같고... 알쏭달쏭하네요
GCC에서..
long 과
long double 은
4바이트로 같습니다.
컴파일 호환성을 위해 정식 자료형이 아닌 long double 을 수용할 뿐입니다.