2013-05-23 3 views
3

항상 정밀도를 유지하기 위해 부동 소수점 값을 10으로 스케일링하여 정밀도를 유지합니까?항상 부동 소수점을 10으로 스케일링합니다.

이 질문은 어떤 수를 Math.pow (10,16) > Math.pow (2,53)

로, Math.pow (2,53)보다 적은Math.pow (10,-15) 이상되는을 포함 적용 나는 희망이 몇 가지 포인트

0.3 - 0.2 //0.09999999999999998

을 지 웁니다

은 스케일링 수

var a = 0.3; 
var b = 0.2; 

var l = Math.max ("".split.call(a,".")[1].length,"".split.call(b,".")[1].length); 

var c; 

a *= Math.pow (10,l); 
b *= Math.pow (10,l); 

c = a-b; 

c /= Math.pow(10,l); 

console.log(c); //0.1 

그러나 빼기를하고 unprecise 명백한되는 " 정확한 " 결과를 제공합니다.

문제는 임의 부동 소수점 값은 상술 CRITERIAS double value nearest N에 하지 결과 않는 열 (여기서 Math.pow (10 , n<16)<Math.pow(2,53))의 전력 곱한 f<Math.pow(10,-15)을 일치가된다 (b) -N (a) ?, 다시 으로 나눌 때의 동력은?

위의 발췌문에서 설명한 것과 같습니다.

이 실제 계산이 사용에 대한,이 설명에 난`좋지 않은 오해에 대한

그리고 SRY가

을 말았 그냥 궁금 아니에요, 관심의 문제입니다
+0

왜 실행하지 않습니까? 그것은 단지 9007199254740992 반복입니다 :) – mplungjan

+0

@mplungjan 오직'b'가 항상 같은 수 =) – C5H8NNaO4

+1

권자입니다. 수학은 결코 나의 장점이 아니 었습니다 - +1 흥미로운 문자열 캐스팅과 십진수 길이 계산 후 – mplungjan

답변

1

나는 질문의 의도가 잘못 지시되었다고 생각한다.

몇 자릿수의 소수점 숫자에 매우 가까운 이진 부동 소수점 값 a와 b가있는 경우 해당 값에 10의 제곱을 곱하고 10의 제곱으로 나눈 다음 일반적으로 수행합니다 단순히 값을 직접 빼는 것보다 나은 결과를 제공하지 않습니다. 곱셈과 나눗셈 각각은 종종 반올림 오류를 유발하며, 이는 a와 b를 직접 빼는 것보다 최종 결과의 정확성을 떨어 뜨리는 경향이 있습니다. 따라서이 원형 교차 메서드를 사용하면 아무 것도 얻지 못합니다.

a와 b에는 이미 반올림 오류가 있습니다 (정확히 근처에있는 숫자가 아니며 사용자가 나타내고 자하는 숫자 임). 때때로 계산 된 값 b-a은 부동 소수점 값이 아닙니다. 십진수 숫자의 차이에 가장 가깝습니다 (단 하나의 ULP 거리에 있습니다). 가끔씩, 우회 계산의 반올림 오류 조합은 그 차이에 가까운 결과를 제공 할 것이지만, 이는 설계보다 우연의 문제 (사실상 우연)입니다.

관련된 힘이 작고 (b-a)*p의 반올림 오류가 항상 0.5보다 작 으면 Math.round((b-a)*p)/p을 계산하면 최상의 결과를 얻을 수 있습니다.

어쨌든 두 방식 모두 계산을 설계하는 좋은 방법이 아닙니다.

Edit3 : 2보다 작은 10의 모든 음수는 입니다. 적절한 pow 구현은 이러한 경우에 대한 정확한 결과를 반환합니다. 가장 낮은 비트 세트의 값이 2 -d 인 이중 x를 고려하십시오. 이 double을 곱하면 정수를 생성하는 10의 최소 제곱합은 10 d입니다. 10 d이 2보다 작 으면 및 1 x가 2 보다 작 으면 둘 다 정확하게 나타낼 수 있습니다. 그런 다음 IEEE-754 부동 소수점 연산 사양에 따라 10 d 및 x의 결과는 정확합니다.

+0

주셔서 감사합니다. 의견 및 답변 =) 귀하의 의견에 관해서는 문제. 그러나 나는 당신의 대답이 잘못되었거나, 내 질문이 여전히 나를 위해 질문에 대답하지 않기 때문에, 내 말은, ** ** float 값, 거기에있는 질문에 언급 된 criterias *' f (Math.pow (10, n <16) C5H8NNaO4

+0

실제로 계산을하고 싶지 않습니다.그것은 호기심에 관한 질문입니다. – C5H8NNaO4

+0

@ C5H8NNaO4 : 나는 Edit3에 댓글을 달았습니다. 그러나 이것은 설명 된 목적을 위해 본질적으로 쓸모가 없습니다. "정수를 얻을 때까지 10을 곱하십시오"하려면 2 ** - 1 비트에서 최소값 세트 비트까지의 비트 수를 곱해야합니다. 이것은 일반적으로 숫자와 연결할 수있는 * 십진 * 숫자의 수와 다릅니다. 예 : '1.15'의 경우 10 ** 2가 아닌 10 ** 51이 필요합니다. –

관련 문제