我遇到了一些問題,它驅使我瘋了。加入和減去浮點數從無符號短在C
我有這樣
float a;
unsigned short b;
b += a;
當a
代碼爲負,b
將會香蕉。
我甚至做了投
b += (unsigned short) a;
,但它不工作。
我做錯了什麼?我怎樣才能將float添加到未簽名的short?
供參考: 當「a」爲-1,b爲0,則我會看到「B + = A」會給B = 65535
我遇到了一些問題,它驅使我瘋了。加入和減去浮點數從無符號短在C
我有這樣
float a;
unsigned short b;
b += a;
當a
代碼爲負,b
將會香蕉。
我甚至做了投
b += (unsigned short) a;
,但它不工作。
我做錯了什麼?我怎樣才能將float添加到未簽名的short?
供參考: 當「a」爲-1,b爲0,則我會看到「B + = A」會給B = 65535
您正在觀察所述浮體的組合被轉換成一個整數和無符號整數環繞(https://stackoverflow.com/a/9052112/1149664)。
考慮
b += a
例如與a = -100.67
您負值添加到簽名的數據類型,並取決於b
結果的初始值奧特是負的。爲什麼你有這個想法使用一個無符號短,而不僅僅是float
或double
這個任務?
這聽起來更像是評論而不是答案。 –
你希望b是正數(它是無符號的),但是a可以是負數。只要a不大於b,就可以。這是第一點。
第二 - 當您將陰性值轉換爲unsign時..結果應該是什麼?數字符號存儲在最高有效位中,負數值爲1.當數值無符號時,如果最高有效位爲1,則該值非常高,與負數無關。
也許嘗試b - = fabs(a)爲負a。這不是你要找的東西嗎?
通過顯示您遇到麻煩的實際值並解釋您期望得到的值,可以改進您的問題。
但在此期間,在浮動C11 6.3.1.4/1到整數轉換的定義是:
當真實浮動類型的有限值轉換爲比_Bool以外的整數類型,小數部分被丟棄(即,該值被截斷爲零)。如果整數部分的值不能用整數類型表示,則行爲是未定義的。
此進場在其中b + a
的結果,這是一個float
,被分配回b
點。回想一下,b += a
相當於b = b + a
。
如果b + a
是-1
或更大程度一個負數,則其組成部分超出範圍爲unsigned short
所以代碼使得undefined behaviour這意味着什麼都可能發生;包括但不限於去香蕉。
甲腳註重複浮子沒有首先被轉換爲一個帶符號的整數,然後到unsigned short
點:
操作執行時整數類型的值被轉換成無符號類型的remaindering不需要執行當實際浮動類型的值被轉換爲無符號類型時。因此,便攜式實浮點值的範圍是
(−1, Utype_MAX+1)
正如你可以寫一個改進:
b += (long long)a;
將至少不會造成UB只要a > LLONG_MIN
。
將float
添加到unsigned short
的方法只是簡單地添加它,就像您所做的一樣。如下所述,新增的操作數將進行轉換。
一個簡單的例子,根據你的代碼是:
#include <stdio.h>
int main(void) {
float a = 7.5;
unsigned short b = 42;
b += a;
printf("b = %hu\n", b);
return 0;
}
輸出,勿庸置疑,就是:
b = 49
聲明
b += a;
相當於:
b = b + a;
(除了b
僅評估一次)。當添加(或減去或......)不同類型的操作數時,它們將根據您可在the C standard第6.3.1.8節中找到的一組規則轉換爲常見類型。在這種情況下,b
從unsigned short
轉換爲float
。該添加相當於42.0f + 7.5f
,其產生49.5f
。然後該分配將該結果從float
轉換爲 b`。
如果添加的數學結果是float
範圍(這是不可能的)之外,或者如果它的unsigned short
範圍(這是更可能的)之外,那麼該計劃將有未定義行爲。您可能會在b
中看到一些垃圾值,您的程序可能會崩潰,或者原則上可能會發生其他任何情況。將有符號或無符號整數轉換爲無符號整數類型時,結果將環繞;當將浮點值轉換爲無符號類型時,會出現而不是。
沒有更多信息,不可能告訴你實際上有什麼問題或如何解決問題。
但似乎增加一個unsigned short
和一個float
並將結果存儲在一個unsigned short
是一個不尋常的事情。可能有情況下您需要什麼(如果有的話你需要避免溢出),但它可能是你會是好結果存儲在比unsigned short
以外的東西,也許在float
或double
。 (順便說一句,double
使用往往比float
浮點數據; float
是有用的多爲節省空間,當你有數據很多)
如果你正在做數字轉換,即使是含蓄的,它通常(但絕不總是)表明你首先應該使用不同類型的變量。
適合我。 b = 42,a = -10我得到了32(在ideone.com中是香草c)。顯示一些真實的代碼並解釋香蕉 – pm100
b = 0,a = -1.32e11 –
你爲什麼要這樣做?即使您將負號簽名轉換爲簽名版本,這可能也不符合您的想法。看看它是如何工作的。 -32投給unsigned不只是給你正面的32或類似的東西。這是「香蕉」所指的嗎?沒有人知道什麼「但它不起作用」意味着當你沒有更多的背景。 –