2015-01-12 4 views
5

int의 집합을 곱하고 결과를 오랫동안 변환 할 때 복소 집합을 곱하여 결과를 long으로 변환하는 것과는 반대로 다른 답을 얻습니다. 예 :C#의 곱셈 오류

int a = 5; 
int b = 5; 
int c = 7; 
int d = 6; 
int ee = 6; 
int f = 8; 
int g = 9; 
int h = 6; 
int i = 6; 
int j = 4; 
int k = 8; 
int l = 9; 
int m = 5; 
long x = a * b * c * d * ee * f * g * h * i * j * k * l * m; 

double aa = 5; 
double ab = 5; 
double ac = 7; 
double ad = 6; 
double aee = 6; 
double af = 8; 
double ag = 9; 
double ah = 6; 
double ai = 6; 
double aj = 4; 
double ak = 8; 
double al = 9; 
double am = 5; 
long y = (long)(aa * ab * ac * ad * aee * af * ag * ah * ai * aj * ak * al * am); 

아무도 이런 일이 발생하는 이유를 말해 줄 수 있습니까? 감사합니다

+2

즉 같은 결과를 얻을 것이다, 아니다 long''와''double'''때문에 '다른 것들이 있습니다 –

+2

Double과 float __cannot__은 2의 거듭 제곱이 아닌 한 100 %의 정밀도를 가진 숫자를 유지합니다. 대신 __approximations__ 만 보유합니다. 따라서 십진수가 표시되는 이유 – TaW

+1

프로젝트 설정에서 오버플로 검사를 활성화하는 것이 좋습니다 최소한 디버그 빌드 용). – CodesInChaos

답변

13

당신은 정수 오버 플로우있어 : 이이 Int32 지금까지

a * b * c * d * ee * f * g * h * i * j * k * l * m 

으로 해석된다 Int64 (long)로 변환 단지보다. 구현을 수정하려면 처음에 long 인 모든 변수를 으로 선언하십시오.

long a = 5; 
    long b = 5; // actually, not necessary, since a * b will be long, but safer 
    long c = 7; 
    ... 
    long m = 5; 

    long x = a * b * c * d * ee * f * g * h * i * j * k * l * m; 
+5

그것들 모두를 '길게'만들 필요조차 없습니다. – ChrFin

+2

@ChrFin : 당신은 '계산을 강요하십시오.'라고 쓰면됩니다. 'long z = (long) a * b * c * d * e * f * g * h * i * 맞습니다.이 경우 기술적으로 * 첫 번째 인수 만 * Int64 형식이어야합니다. 그러나 정수 오버플로에 직면 할 때 "64 비트 표현으로 작업해야하며 모든 정수 인수를 Int64'로 변환해야합니다. –

+0

@DmitryBychenko : 감사합니다. 이런 식으로 생각했습니다. – Ka0s

5

아마도 곱셈 결과가 너무 커서 Int32를 수용하기에는 크기가 크지 만 그 이유는 이것이 두 배로 유지 될 수 있기 때문입니다. 0x000000057994b000

Int32은 하위 8 개 진수 값을 저장할 수 =

X = 0x000000007994b000
Y :

좀 더 구체적인 진수에서 x 및 y에서 보면된다. 이것이 x이 잘못된 번호 인 이유입니다. 가장 낮은 8 진수 값은 정확하지만 상단은 잘립니다. 두 int을 곱 때마다 int이 있기 때문에

2

나는 그것을 간단한 검색을 줄뿐만 아니라 심지어 스크립트에 대한 몇 가지 테스트를 실행하고 나는

<script> 
     var a = 5; 
     var b = 5; 
     var c = 7; 
     var d = 6; 
     var ee = 6; 
     var f = 8; 
     var g = 9; 
     var h = 6; 
     var i = 6; 
     var j = 4; 
     var k = 8; 
     var l = 9; 
     var m = 5; 
     var x = a * b * c * d * ee * f * g * h * i * j * k * l * m; 
     var y = eval(a * b * c * d * ee * f * g * h * i * j * k * l * m); 
     document.writeln("RESULT X : " + x); 
     document.write("<br>"); 
     document.writeln("RESULT Y : " + y); 
    </script> 

다음 결과, 나는 그것을 테스트 스크립트 형식으로 을 발견하고 결과가 23514624000했다 모두 xy에 대해 C#에서 모든 정수를 곱하면 결과는 정수가되지만 int.MAX = 2147483647은 실제 결과보다 작음을 알 수 있습니다. 결과적으로 long x= a * b * c * d * ee * f * g * h * i * j * k * l * m;에 할당하면 원래 값이 잘리고, 그리고 다른 사람에게서 당신이 코드를 사용할 수 있습니다 모두 같은 결과를 원하는 경우 sult는

이제
int a = 5; 
int b = 5; 
int c = 7; 
int d = 6; 
int ee = 6; 
int f = 8; 
int g = 9; 
int h = 6; 
int i = 6; 
int j = 4; 
int k = 8; 
int l = 9; 
int m = 5; 
long x = (long)a * b * c * d * ee * f * g * h * i * j * k * l * m; 

double aa = 5; 
double ab = 5; 
double ac = 7; 
double ad = 6; 
double aee = 6; 
double af = 8; 
double ag = 9; 
double ah = 6; 
double ai = 6; 
double aj = 4; 
double ak = 8; 
double al = 9; 
double am = 5; 
long y = (long)(aa * ab * ac * ad * aee * af * ag * ah * ai * aj * ak * al * am); 
Console.WriteLine(x); 
Console.WriteLine(y); 
Console.ReadKey(); 

당신이 23514624000