2017-01-25 9 views
-1

画像に次の2つのプリントが同じでないのはなぜですか?C型キャスティングの問題(FloatがIntにアサート)

uint16_t linCalc(uint16_t adcAverage){ 
    float k = 2500/2500; 
    float j = 8000/5000; 
    int a = 1000 * (j - k); 
    printf("a = %d\n", a); 
    k = 1; 
    j = 1.6; 
    int b = 1000 * (j - k); 
    printf("b = %d\n", b); 
} 
b = 600 
a = 0 
b = 600 
a = 0 
b = 600 
a = 0 
b = 600 
a = 0 
b = 600 
a = 0 
b = 600 
a = 0 
b = 600 
a = 0 
b = 600 

フロート式が計算されている(私も彼らの宣言で、同様のフロートを型キャストしようとした)の前にint型としてアサートされているようです。

+0

権利でありますあなたが持っているように、あなたのフロートは 'int'に劣化します。 –

+2

あなたの質問にコードで画像を貼り付けないでください。実際のコードを貼り付けます。 – DyZ

+2

'2500'、 '8000'、および '5000'はすべて整数リテラルなので、除算には整数の演算が使用され、その後は 'k'および' j'への代入のためにfloatに変換されます。しかし、 'b'の場合、浮動小数点値の減算によって、浮動小数点での乗算も行われ、後で' b'への代入のために 'int'に変換されます。だから、別の結果。 – Dmitri

答えて

5

8000/5000は、両方のオペランドがintの定数であるため、整数除算を実行するため、これらは同じではありません。除算の結果は1です。

浮動小数点除算を強制するには、少なくとも1つのオペランドをfloatにする必要があります。それはいくつかの方法、すなわち(および好ましい順に)で達成することができる。

  1. 8000.0f/5000
  2. (float)8000/5000
+1

注: 'f'を提案する:' float f1 =(float)1000000000000000000000000; 'は問題ですが、' float f2 = 1000000000000000000000000.0f; 'は問題ありません。キャスティングはめったに最善のアプローチではありません。 – chux

+1

@chux - 良い点が追加されました。ありがとう。 – StoryTeller

1

float j = 8000/5000収率1。 rhs式8000/5000は、評価後にfloatに変換されます。 80005000はデータ型がintのリテラルなので、8000/5000intとなります。

float j = 8000.0/5000.0を書き込むと浮動小数点除算が得られます。

-1

第1の場合、k = 1.0およびj = 1.0であり、第2のケースでは、k = 1.0およびj = 1.6である。 これは、最初の場合、整数を別の整数で割って結果が整数になるため、k、jに代入されるときにfloatに格納されるためです。

[email protected]:/tmp/so$ cat main.c 
 
#include <stdio.h> 
 
#include <stdlib.h> 
 

 
int main(void) 
 
{ 
 
\t float k; 
 
\t float j; 
 
\t int a; 
 
\t int b; 
 
\t 
 
\t k = 2500/2500; 
 
\t j = 8000/5000; 
 
\t printf("k = %f, j = %f\n", k, j); 
 
\t a = 1000 * (j - k); 
 
\t printf("a = %d\n", a); 
 
\t k = 1; 
 
\t j = 1.6; 
 
\t b = 1000 * (j - k); 
 
\t printf("b = %d\n", b); 
 
\t return (EXIT_SUCCESS); 
 
} 
 
[email protected]:/tmp/so$ gcc -Wall -Werror -pedantic -Wextra main.c -o ben && ./ben 
 
k = 1.000000, j = 1.000000 
 
a = 0 
 
b = 600 
 
[email protected]:/tmp/so$

あなたが明示的部門でフロート(あるいは少なくとも一つのフロート)を使用することができないようにしたい場合:

[email protected]:/tmp/so$ cat main.c 
 
#include <stdio.h> 
 
#include <stdlib.h> 
 

 
int main(void) 
 
{ 
 
\t float k; 
 
\t float j; 
 
\t int a; 
 
\t int b; 
 
\t 
 
\t k = 2500.0/2500; 
 
\t j = 8000.0/5000; 
 
\t printf("k = %f, j = %f\n", k, j); 
 
\t a = 1000 * (j - k); 
 
\t printf("a = %d\n", a); 
 
\t k = 1; 
 
\t j = 1.6; 
 
\t b = 1000 * (j - k); 
 
\t printf("b = %d\n", b); 
 
\t return (EXIT_SUCCESS); 
 
} 
 
[email protected]:/tmp/so$ gcc -Wall -Werror -pedantic -Wextra main.c -o ben && ./ben 
 
k = 1.000000, j = 1.600000 
 
a = 600 
 
b = 600 
 
[email protected]:/tmp/so$

関連する問題