在C中添加和减去来自unsigned short的float

时间:2015-11-03 21:58:36

标签: c

我遇到了一些问题,这让我疯了。

我有这样的代码

float a;
unsigned short b;

b += a;

a为负数时,b正在使用香蕉。

我甚至做过演员

b += (unsigned short) a;

但它没有用。

我做错了什么?如何将float添加到unsigned short?

供参考: 当' a'是-1而b是0然后我会看到' b + = a'将给出b = 65535。

4 个答案:

答案 0 :(得分:2)

通过显示您遇到问题的实际值,并解释您希望获得的价值,可以改善您的问题。

但与此同时,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

  

当实数浮点类型的值转换为无符号类型时,无需执行将整数类型的值转换为无符号类型时执行的剩余操作。因此,便携式实际浮动值的范围是(−1, Utype_MAX+1)

作为改进,你可以写:

b += (long long)a;

至少不会导致UB a > LLONG_MIN

答案 1 :(得分:2)

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转换为unsigned short, and the result, 49 is stored in b`。

如果加法的数学结果超出float(不太可能)的范围,或者它超出unsigned short的范围(更有可能),那么程序将具有未定义的行为。您可能会在b中看到存储的垃圾值,您的程序可能会崩溃,或者原则上确实会发生其他任何事情。将有符号或无符号整数转换为无符号整数类型时,结果将被包围;将浮点值转换为无符号类型时, not 会发生这种情况。

如果没有更多信息,就无法确定您实际遇到的问题或解决方法。

但似乎添加unsigned shortfloat并将结果存储在unsigned short中似乎是不寻常的事情。在某些情况下,它可能正是您所需要的(如果是这样,您需要避免溢出),但您可能最好将结果存储在除{{{{{{{{{{{{{{{{{{{{{{{{{ 1}},也许在unsigned shortfloat中。 (顺便提一下,doubledouble更常用于浮点数据; float主要用于在拥有 lot 数据时节省空间。 )

如果您正在进行数字转换,即使是隐式转换,它通常(但绝不总是)表明您应该首先使用不同类型的变量。

答案 2 :(得分:-1)

您正在观察被转换为整数的浮点数和无符号整数环绕(https://stackoverflow.com/a/9052112/1149664)的组合。

考虑

b += a 

例如,对于a = -100.67,您为已签名的数据类型添加了一个负值,并且根据b的初始值,结果必须为负数。为什么你有想法使用未签名的短片而不只是floatdouble来执行此任务?

答案 3 :(得分:-1)

你希望b是正数(它是无符号的),但是a可以是负数。只要a不大于b就可以了。这是第一点。

第二 - 当你输出负值以取消签名时......实际上结果应该是什么?数字符号存储在最高有效位中,对于负数值,它为1.当值为无符号时,如果最高有效位为1,则该值非常高并且与负数值没有任何共同点。

也许尝试b - = fabs(a)表示否定a。这不是你想要的吗?