source

소수점 이하를 2배로 이동

factcode 2022. 9. 20. 23:51
반응형

소수점 이하를 2배로 이동

그래서 나는 1234와 같은 이중집합이 있습니다. 12.34가 되도록 소수점 자리를 옮기고 싶습니다.

이렇게 하려면 1에서 1234를 두 번 곱합니다

double x = 1234;
for(int i=1;i<=2;i++)
{
  x = x*.1;
}
System.out.println(x);

그러면 "12.3400000000002"라는 결과가 출력됩니다.

단순히 소수점 2자리까지 포맷하지 않고 더블스토어 12.34를 올바르게 할 수 있는 방법은 없을까?

「 」를 사용하고 double ★★★★★★★★★★★★★★★★★」float반올림을 사용하거나 반올림 오류가 발생할 수 있습니다.작업을 수행할 수 없는 을 사용하십시오.BigDecimal.

문제는 0.1이 정확한 표현이 아니라는 것입니다.또한 계산을 두 번 수행하면 이 오류가 복합적으로 나타납니다.

단, 100은 정확하게 나타낼 수 있으므로 다음을 시도해 보십시오.

double x = 1234;
x /= 100;
System.out.println(x);

인쇄:

12.34

것은 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 맞다.'Double.toString(d)소수 반올림을 대신 수행하지만 많지 않습니다.반올림하지 않으면 어떤 모양일지 궁금할 경우:

System.out.println(new BigDecimal(0.1));
System.out.println(new BigDecimal(x));

인쇄:

0.100000000000000005551115123125782702118158340454101562
12.339999999999999857891452847979962825775146484375

즉, 명시적으로 이 작업을 수행하는지 여부에 관계없이 부동소수점에서의 합리적인 답변에는 반올림이 불가피합니다.


★★★★★★x / 100 ★★★★★★★★★★★★★★★★★」x * 0.01반올림 오차는 완전히 동일하지 않습니다.는 첫 , "x"는 x의 값에 따라 때문입니다.0.01두 번째 라운드 오류가 수정되었습니다.

for(int i=0;i<200;i++) {
    double d1 = (double) i / 100;
    double d2 = i * 0.01;
    if (d1 != d2)
        System.out.println(d1 + " != "+d2);
}

인쇄하다

0.35 != 0.35000000000000003
0.41 != 0.41000000000000003
0.47 != 0.47000000000000003
0.57 != 0.5700000000000001
0.69 != 0.6900000000000001
0.7 != 0.7000000000000001
0.82 != 0.8200000000000001
0.83 != 0.8300000000000001
0.94 != 0.9400000000000001
0.95 != 0.9500000000000001
1.13 != 1.1300000000000001
1.14 != 1.1400000000000001
1.15 != 1.1500000000000001
1.38 != 1.3800000000000001
1.39 != 1.3900000000000001
1.4 != 1.4000000000000001
1.63 != 1.6300000000000001
1.64 != 1.6400000000000001
1.65 != 1.6500000000000001
1.66 != 1.6600000000000001
1.88 != 1.8800000000000001
1.89 != 1.8900000000000001
1.9 != 1.9000000000000001
1.91 != 1.9100000000000001

메모: 이것은 시스템(또는 PSU)의 랜덤성과는 무관합니다.이는 표현 오류로 인해 매번 동일한 결과가 발생합니다.★★★★의 double될 수 있는 않는

-10진수를 합니다.BigDecimaldouble0.1과 같은 숫자를 정확하게 나타낼 수 없습니다. 한정된 소수 자릿수로 1/3의 값을 정확하게 쓸 수 있는 것과 같습니다.

포맷만 하면 printf를 사용해 보세요.

double x = 1234;
for(int i=1;i<=2;i++)
{
  x = x*.1;
}
System.out.printf("%.2f",x);

산출량

12.34

금융 소프트웨어에서는 페니에 정수를 사용하는 것이 일반적입니다.학교에서 우리는 부동소수점 대신 고정소수를 사용하는 법을 배웠지만, 그것은 보통 2의 거듭제곱이다.페니를 정수로 저장하는 것을 "고정점"이라고도 합니다.

int i=1234;
printf("%d.%02d\r\n",i/100,i%100);

수업 시간에, 우리는 일반적으로 어떤 숫자가 베이스로 정확하게 표현될 수 있는지 질문을 받았다.

★★★의 base=p1^n1*p2^n2......인 수 N=n*p1^m1*p2^m2이면 N이면 N이다.

let let 렛츠고base=14=2^1*7^11/1/ 1 1/ 수 1/3은 수 1/7 1/14 1/28 1/28 1/49는 나타낼 수 없습니다.

저는 금융 소프트웨어에 대해 알고 있습니다. 티켓마스터의 재무보고서를 VAX ASM에서 PASCAL로 변환했습니다.그들은 pennies 코드와 함께 그들만의 formatln()을 가지고 있었다.32비트 정수로는 부족하기 때문입니다.+/- 20억 페니는 2000만 달러이고 월드컵이나 올림픽을 위해 넘쳐난다는 것을 잊고 있었습니다.

나는 비밀을 지킬 것을 맹세했다.아, 그렇군요.학술지에서는 좋으면 출판하고 업계에서는 비밀에 부칩니다.

정수 표현을 시도할 수 있습니다.

int i =1234;
int q = i /100;
int r = i % 100;

System.out.printf("%d.%02d",q, r);

이는 컴퓨터가 부동소수점 숫자를 저장하는 방식으로 인해 발생합니다.그들은 정확히 그렇게 하지 않는다.프로그래머로서 이 부동소수점 가이드를 읽고 부동소수점 숫자의 처리의 시행과 고충을 숙지해야 합니다.

많은 게시물이 Big Decimal을 사용한다고 언급했는데 아무도 Big Decimal을 기반으로 정답을 제시하지 않는 것이 재미있습니까?왜냐하면 Big Decimal을 사용하더라도 이 코드에서 알 수 있듯이 여전히 잘못될 수 있기 때문입니다.

String numstr = "1234";
System.out.println(new BigDecimal(numstr).movePointLeft(2));
System.out.println(new BigDecimal(numstr).multiply(new BigDecimal(0.01)));
System.out.println(new BigDecimal(numstr).multiply(new BigDecimal("0.01")));

이 출력을 제공합니다.

12.34
12.34000000000000025687785232264559454051777720451354980468750
12.34

BigDecimal 컨스트럭터에서는 숫자 컨스트럭터보다 String 컨스트럭터를 사용하는 것이 좋다고 구체적으로 언급하고 있습니다.궁극의 정밀도는 옵션의 MathContext에도 영향을 받습니다.

BigDecimal Javadoc에 따르면 String 생성자를 사용하면 정확히 0.1과 동일한 BigDecimal을 생성할 수 있습니다.

네, 있어요.각 이중 연산을 수행할 때마다 정확도가 떨어질 수 있지만, 각 연산의 정확도는 다르므로 올바른 연산 시퀀스를 선택하여 최소화할 수 있습니다.예를 들어 숫자 집합을 곱하는 경우 곱하기 전에 지수별로 집합을 정렬하는 것이 가장 좋습니다.

숫자 계산과 관련된 괜찮은 책은 이것을 묘사하고 있다.예: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

그리고 당신의 질문에 답하기 위해서:

곱셈 대신 나누기를 사용하면 올바른 결과를 얻을 수 있습니다.

double x = 1234;
for(int i=1;i<=2;i++)
{
  x =  x / 10.0;
}
System.out.println(x);

아니요. Java 부동소수점 유형(실제로는 모든 부동소수점 유형)은 크기와 정밀도의 트레이드오프이기 때문입니다.많은 작업에 매우 유용하지만 임의의 정밀도가 필요한 경우BigDecimal.

언급URL : https://stackoverflow.com/questions/4937402/moving-decimal-places-over-in-a-double

반응형