2013-12-17 6 views
0

일부 C 코드는 int이 -145로 설정되어 있습니다. 형식에 따라 값은 0.00 또는 -145으로 반환됩니다. 그것은 첫 번째 줄은 0.00 반환되는 방법은 다음printf 형식 f 대 d 대 파이썬

int a = -145; 

printf("%.2lf", a); // returns 0.00 
printf("%.2ld", a); // returns -145 

첫 번째 질문을 가지고 있습니다? 두 번째 질문은 파이썬에서 0.00을 반환하는 방법입니다. 내가 해봤 많은 반복 중

, 여기에 몇 가지 :

a = -145 

"%0.2lf" % a # -145.00 
"%0.2ld" % a # -145 
"%0.2li" % a # -145 
"%0.2f" % a # -145.00 
+1

물론 @ouah는 정확합니다. C는 사용자가 보여준 코드에서 어떤 일이 발생하는지에 대해 아무 것도 정의하지 않습니다. 그것은 플랫폼에 따라 다를 것이고, 횡포를 표시하는 것에서 segfault로 붕괴 될 수 있습니다. C의'printf' 패밀리는이 방법으로 오류를 범하기 쉽다. 두 번째 질문에 대답하기 위해, 당신은 파이썬을 이런 식으로 "트릭"할 수 없습니다. 파이썬이 -145를 정수 이외의 것으로 취급 할 방법이 없습니다. –

+0

이상하지만 괜찮습니다. –

답변

4
int a = -145; 

printf("%.2lf", a); // returns 0.00 
printf("%.2ld", a); // returns -145 

두 함수 호출은 정의되지 않은 동작을 호출합니다. int을 인쇄 할 올바른 변환 지정자는 d이 아니고 lf (double의 경우)이 아니고 ld (long의 경우)이 아닙니다.

0

두 번째 질문은 0.00을 파이썬으로 반환하는 방법입니다.

당신이 주장하는 경우 :

import struct 

def misinterpret_int_as_double(n): 
    int_bytes = struct.pack('i', n) 
    padding = b'\x00' * (struct.calcsize('d') - struct.calcsize('i')) 
    return struct.unpack('d', int_bytes + padding)[0] 

>>> misinterpret_int_as_double(-145) 
2.1219957193e-314 

이 본질적으로 당신의 C 코드가 무대 뒤에서 무엇을하고 있는지. C는 varargs 함수를 호출 할 때 ... 부분에 전달 된 인수에 대해 컴파일 할 때 (컴파일시 또는 런타임) 형식 검사를 수행하지 않습니다. 무엇 발생하는 printf의 인수를 저장하는 메모리가 포함되어 있습니다 :

  1. "%.2lf 리터럴 문자열에 대한 포인터.
  2. 숫자 -145를 나타내는 바이트. (x86-32 또는 x86-64에서는 4 바이트 91 FF FF FF입니다.)
  3. 일부 가비지 데이터입니다. (위의 파이썬 코드에서, 이것은 모두 제로로 가정하지만 C 프로그램에서이 일 필요는 없다.)

printf 기능은 lf 지정자를보고하고 double을 기대하고있다. 따라서 다음 바이트 인 91 FF FF FF xx xx xx xx (여기서 xx = 가비지)을 하나로 해석합니다. 쓰레기의 가능한 값의 1/4 (00 00 00 00 포함)의 경우 숫자는 0으로 반올림하기에 충분히 작습니다.

4 바이트의 int 및 8 바이트의 double을 가진 리틀 엔디안 시스템을 보유하고 있다는 점에 유의하십시오. 함수 인수는 메모리에서 오름차순으로 전달됩니다. 그리고 코드가 segfault하지 않습니다. 다른 하드웨어/OS/컴파일러 조합의 YMMV. 그것이 정의되지 않은 동작을하는 방식입니다.

Python은 안전하게 입력되므로 다른 방식으로 작동합니다. “ 형식이 str% 연산자 인 %으로 잘못 전달되면 마법 __float__ 메서드 (또는 __str__ 또는 __int__ 또는 어떤 형식인지에 관계없이)를 호출하여 피연산자를 올바른 형식으로 자동 변환합니다.