그건 일일이 유효숫자를 정해야 하므로 별로 좋은 방법이 아닌 것 같습니다. 위에 언급한 실수 46.0001과 46.4는 예시로 제시한 것입니다. 임의의 실수를 printf로 정확하게 출력할 수 있는 방법을 질문드린 겁니다. 저에게는 이 문제가 상당히 중요하면서도 꽤 골칫거리네요.
double이든 float이든 어떤 비트열인데, 가령 45.4와 45.4f가 비트수준에서도 같기를 바라신다면, 직접 비교할게 아니라 입력 받을때 float을 적당한 int로 변환하는 함수와 double을 적당한 int로 변환하는 함수를 만드셔서 비교해야겠죠. 그리고 각 함수는 45.4를 변환한 값과 45.4f를 변환한 값이 같은 값을 반환하도록 잘 설계하셔야합니다.
물론 사칙연산을 넣으시려면 골때릴거예요. (a*b)/c와 (a/c)*b가 반올림을 어디서, 어떤 순서로 하느냐에 따라 같지 않을수도 있거든요.
잘리는 문제가 왜 생길까요? 그건 10진과 2진의 차이에서 오는 것입니다. 소수점 아래 숫자가 존재하는 10진 숫자가 비록 유한소수일지라도 2진으로 고치면 무한소수가 될 수 있습니다. 바로 이진으로 고쳤을 때 무한소수를 줄여 표현하기 위한 방법이 바로 f이며 배정밀도 표현법이기도 한 것이죠. 실수가 저장되는 원리를 몰라 그러는 것이 아닙니다. printf로 위에 언급한 숫자를 출력할 때, 입력된 값을 제대로 출력하는 것이 아니라 오차를 지닌 값을 변환해서 출력한다는 문제가 있는 것으로 추정됩니다. 이건 추정일 뿐 반드시 그렇다고 확신하고 있는 것도 아닙니다. 이진 무한소수에 대한 오차를 줄이거나 보다 정확한 계산을 하기 위해서는 문자열을 사용하는 방법밖에 없겠군요. 저도 처음에 그런 생각을 했었습니다. 다만 그렇게 하면 메모리를 더 많이 사용하기 때문에 보류했을 뿐이죠... 아직도 중세에 살고 있는 것 같군요....
f는 단지 부동소수점 상수를 float형으로 한정하기 위한 접두사일 뿐이고,
10진에서 2진으로 정확하게 바뀌지 않는 것은 float형이나 double형이나 마찬가지이며,
float형은 보통 단정도 또는 단정밀도 라고 하지 배정밀도라고 하진 않고,
배정밀도는 말 그대로 단정밀도에 비해 용량이 2배일 뿐, 다른 목적이 있는건 아닙니다.
님이 하는 말을 보면 별로 제대로 이해한거 같다는 생각이 도저히 안듭니다.
뭐 모를 수도 있고 이해 못할 수도 있죠.
그리고 그런 사람들을 위해 여기 질문 게시판이 있는거고.
근데 문제는 님이 다른 사람들 말을 전혀 듣지 않는다는 겁니다.
string으로 받아서 뒤에 f를 떼고 출력시키면 될
string으로 받아서 뒤에 f를 떼고 출력시키면 될 것 같은데요
피할 수 있을때 즐겨라! http://melotopia.net/b
이 분 말씀대로 저장은 string으로 하고
이 분 말씀대로 저장은 string으로 하고 수치연산할때만 실수형으로 바꿔서 계산하는...
뭐 그런 라이브러리를 만들어서 할 수밖에 없지 않나 싶군요.
포맷이 문제라면
이렇게 하면 됩니다.
그건 일일이 유효숫자를 정해야 하므로
그건 일일이 유효숫자를 정해야 하므로 별로 좋은 방법이 아닌 것 같습니다. 위에 언급한 실수 46.0001과 46.4는 예시로 제시한 것입니다. 임의의 실수를 printf로 정확하게 출력할 수 있는 방법을 질문드린 겁니다. 저에게는 이 문제가 상당히 중요하면서도 꽤 골칫거리네요.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
정확히 말해서, "임의의 실수"는 컴퓨터에서 표현할
정확히 말해서, "임의의 실수"는 컴퓨터에서 표현할 수 없습니다.
double이든 float이든 어떤 비트열인데, 가령 45.4와 45.4f가 비트수준에서도 같기를 바라신다면, 직접 비교할게 아니라 입력 받을때 float을 적당한 int로 변환하는 함수와 double을 적당한 int로 변환하는 함수를 만드셔서 비교해야겠죠. 그리고 각 함수는 45.4를 변환한 값과 45.4f를 변환한 값이 같은 값을 반환하도록 잘 설계하셔야합니다.
물론 사칙연산을 넣으시려면 골때릴거예요. (a*b)/c와 (a/c)*b가 반올림을 어디서, 어떤 순서로 하느냐에 따라 같지 않을수도 있거든요.
피할 수 있을때 즐겨라! http://melotopia.net/b
저번 글도 그렇고 이 글도 그렇고 실수가 저장되는
저번 글도 그렇고 이 글도 그렇고 실수가 저장되는 원리에 대해 파악을 전혀 못하시는거 같네요.
2진 실수와 10진 실수간에 변환하려면 오차는 어떻게든 생길수밖에 없습니다.
실수를 10진으로 저장하는 별도의 라이브러리를 사용하던지
오차를 감안한 코딩을 해야합니다.
f이면 비트가 작으니 변환시 잘리는 경우가 생길 수 있죠.
잘리는 문제가 왜 생길까요? 그건 10진과 2진의 차이에서 오는 것입니다. 소수점 아래 숫자가 존재하는 10진 숫자가 비록 유한소수일지라도 2진으로 고치면 무한소수가 될 수 있습니다. 바로 이진으로 고쳤을 때 무한소수를 줄여 표현하기 위한 방법이 바로 f이며 배정밀도 표현법이기도 한 것이죠. 실수가 저장되는 원리를 몰라 그러는 것이 아닙니다. printf로 위에 언급한 숫자를 출력할 때, 입력된 값을 제대로 출력하는 것이 아니라 오차를 지닌 값을 변환해서 출력한다는 문제가 있는 것으로 추정됩니다. 이건 추정일 뿐 반드시 그렇다고 확신하고 있는 것도 아닙니다. 이진 무한소수에 대한 오차를 줄이거나 보다 정확한 계산을 하기 위해서는 문자열을 사용하는 방법밖에 없겠군요. 저도 처음에 그런 생각을 했었습니다. 다만 그렇게 하면 메모리를 더 많이 사용하기 때문에 보류했을 뿐이죠... 아직도 중세에 살고 있는 것 같군요....
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
그래서 10진은 불편하죠.
그래서 10진은 불편하죠. 8진수 내지는 16진수를 사용하면 사람과 컴퓨터 간의 무한소수의 문제는 원만하게 해결된 것 같은데요...
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
hexadecimal floating-point
hexadecimal floating-point literal이 뭔지 찾아보라고 지난번에 말씀드린거 같은데...
f는 단지 부동소수점 상수를 float형으로 한정하기
f는 단지 부동소수점 상수를 float형으로 한정하기 위한 접두사일 뿐이고,
10진에서 2진으로 정확하게 바뀌지 않는 것은 float형이나 double형이나 마찬가지이며,
float형은 보통 단정도 또는 단정밀도 라고 하지 배정밀도라고 하진 않고,
배정밀도는 말 그대로 단정밀도에 비해 용량이 2배일 뿐, 다른 목적이 있는건 아닙니다.
님이 하는 말을 보면 별로 제대로 이해한거 같다는 생각이 도저히 안듭니다.
뭐 모를 수도 있고 이해 못할 수도 있죠.
그리고 그런 사람들을 위해 여기 질문 게시판이 있는거고.
근데 문제는 님이 다른 사람들 말을 전혀 듣지 않는다는 겁니다.
그래도 printf가 입력된 제 값을 그대로 출력만 해준다면,
그래도 printf가 입력된 제 값을 그대로 출력만 해준다면, 그건 정말 황송할 일입니다. 그럼 제가 질문드렸던 모든 문제도 한 큐에 해결될텐데요... 너무 아쉽죠..
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
그런 걸 만들 바에는 차라리 모든 실수를 double로 표현하는 게
언급한 것을 저리 어렵게 만들 바에는 차라리 모든 실수를 double로 표현하는 게 나을 것도 같네요. 그럼 지금껏 생각해 만든 건 아무 의미가 없는 매몰비용인데....
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
모든 실수가 double이라고 해서 별로 다른건
모든 실수가 double이라고 해서 별로 다른건 없습니다.
오차가 크냐 작냐의 문제만 있을 뿐이고
3이 2.9999999,,,가 되어 문제가 생길 수 있는건 마찬가지입니다.
그래도 비교연산에서 발생하는 문제는
그래도 비교연산에서 발생하는 문제는 해결이 가능합니다. 제가 만들었던게 f와 f가 없는 실수 자료형은 비교하는 비교연산자였습니다.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
3이 2.9999...가 되고 또다른 3이
3이 2.9999...가 되고 또다른 3이 2.9999...가 되서 그 두개가 서로 같다고 판정되는게 참으로 해결이 잘 된 것이겠습니다.
무슨 3이 2.9999...라는 것인지?
무슨 3이 2.9999...라는 것이죠. 이것은 다음과 같이 정규화될 수 가 있어요.
1.1X2^1
여기서 1.1은 2진수 입니다. 가수는 1이네요. 이진화할 때 가수가 무한하지 않잖아요. 이런 것은 그런 오차 문제 같은 게 발생하지 않는답니다.
제대로 알고 답변을 하는 것입니까? 나, 참...
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
생각없이 잘못된 숫자를 예로 들은 것에 대해서
생각없이 잘못된 숫자를 예로 들은 것에 대해서 진심으로 사과를 드리는 바입니다.
그런데... 그래서 님이 만든 그 비교 라이브러리란거 성공했어요? 풉...
가서 님 코드 내에 있는 float를 다 double로 고쳐 보시고, 잘 안 되시면 다시 오시죠.
또 와서 GNU니 뭐니 헛소리 늘어놓을꺼 뻔히 보이긴 하는데... ㅋㅋㅋ
....
다른사람들이 NO 라고 할때 혼자서 TRUE 라고 하는 사람이군요
NO YES 짝이
FALSE TRUE 짝하고 섞였다고 해야되나
어떻게 하면 저런 특이한 정신세계를 가질수 있는지 궁금하네요.
어느 순간 원하는 바가 바뀐것을 보니 뭔가
어느 순간 원하는 바가 바뀐것을 보니 뭔가 잘못됐다는건 느끼신 모양입니다. 그냥 자기가 실수했다는걸 인정하기 싫으신거겠죠.
댓글 달기