2013-02-23 1 views
14

소프트웨어 부동 에뮬레이션 (하드웨어 부동 소수점을 사용할 수 없음)을 지원하는 32 비트 powerpc 커널에서 아래의 C++ 프로그램을 실행할 때 잘못된 조건부 평가가 발생합니다. 어떤 사람들은 잠재적 인 문제가 무엇인지 말해 줄 수 있습니까?부동 소수점 동작이 올바르지 않습니다.

#include <stdio.h> 

int main() { 
    int newmax = 1; 
    if ((newmax + 0.0) > 256) { 
     printf("\nShouldn't be here\n"); 
    } else { 
     printf("\nShould be here\n"); 
    } 
} 

컴파일 : 대상 시스템에

powerpc-linux-g++ -msoft-float -c floating.cxx 
powerpc-linux-g++ -o floating floating.o 

출력 : 를 링크 할 때

[linux:/]$ ./floating 
Shouldn't be here 
+0

커널이란 무엇입니까? 내 최선의 추측은 에뮬레이션이 부동 소수점 표준에 어떻게 든 복종하지 않는다는 것입니다. 정확하지 않은 표현은 0입니다. 또한 기본값 0.0은 float이 아닌 double 값을 사용한다는 점에 유의하십시오. 어쩌면 소프트웨어 에뮬레이터가 이중을 지원하지 않을 수도 있습니다. – speeder

+2

연결할 때 -msoft-float도 지정해야합니다. –

+0

@speeder. 이것은 사용자 정의 2.6.32.59 커널입니다. 나는 이것이 커널에서 소프트웨어 에뮬레이션 문제가 될지 의심 스럽다. – rajachan

답변

1

또한 -msoft 플로트를 지정해야는 -S 플래그와 함께 우리에게 dissassembly주세요 : powerpc-linux-g ++ -msoft-float -c floating.cxx -S -o floating.s

0

먼저 하드웨어 부동 소수점이 비활성화 된 이유는 무엇입니까?

이 형식 때문에 잘못된 순서로 캐스트가 수행 될 수 있습니다.

(double)1 = 0x3FF0000000000000 
(float) 1 = 0x3F800000 

이것은 귀하의 상태입니다.

if ((newmax + 0.0) > 256) 

귀하의 경우 : 1) newmax casting to float 또는 double; 2) 0.0을 첨가; 3) int로 캐스트 된 값을 가져 왔습니다.

컴퓨터에 따라 다르지만 int는 일반적으로 32 비트 값입니다. 그것을 확인하려면 다음을 사용할 수 있습니다 :

어쨌든, 계산 된 값을 int로 변환하면 큰 양수가됩니다. 0x3FF00000

무슨 일이 있었는지, 확인하려면,하지만 분해가 최선의 선택, 당신의 상황에서 나는 그것을 인쇄 할 것이다/또는로 0x100로하지만

0x3F800000, 0x3FF0000000000000하지 비교할 수 있습니다.

아마 그것은별로 도움이되지 못했지만 그것은 단지 내 생각이었습니다.

+0

형식 캐스트가 수행되는 순서는 C++ 표준에 의해 지정됩니다. 부동 소수점 연산이 SW 또는 HW 또는 이들의 혼합으로 수행되는지는 상관하지 않습니다. – MSalters

-1

코드 newmax + 0.0에있는 명령문은 결과를 float 또는 double로 생성하지만 정수 값과 비교됩니다.

따라서이 오류.

int i=1; 
printf("%d",(i+0.0)); 

당신이 상관없이 i 값 결과 0 매번 얻을, 이것 좀보십시오.

int i=1; 
printf("%f",(i+0.0)); 

, 반면에이 오류 커널 오류를 링커에 어셈블러 오류 컴파일러 오류에서 1.0000

0

이 될 수 무엇을 생산하고 있습니다. 다른 사람들이 이미 지적했듯이, -S 옵션을 사용하여 컴파일 결과를 제공했다면, 컴파일러 오류 (이 오류를 일으킬 가능성이 가장 큰 소스)가 확인 될 수 있습니다 (또는 배제됩니다).컴파일러 오류가 아닌 경우 부동 소수점 에뮬레이션에 대한 커널 오류가 문제의 다음 소스 일 수 있습니다.