【问题标题】:c-language data type arithmetic rulesc语言数据类型算术规则
【发布时间】:2011-01-26 03:03:55
【问题描述】:

在 c 编程中,如果我在下面的等式中使用变量 k、X、Y、n(其中 exp() 是数学常数 e 升为 (),pi = 3.14159...,j = sqrt( -1)) 并且这些变量都被声明为 64b 双精度浮点数(其中 X 是复数),输出的结果也将是这种数据类型。

output = k * exp(2*pi*j*X*Y/n)

现在,如果我想尝试更智能地管理内存,我想做

k、Y 和 n 为 32 位无符号长整数(0 到 4294967295),并且

pi、j 和 X 为 32 位浮点数。

我的问题是,输出的结果是数据类型 float(希望如此)还是 unsigned long int?也就是说,C 语言是否有一些默认规则可以智能地处理浮点数和整数相乘并将结果作为浮点数返回,或者我必须使用类型转换等手动管理它?只是想知道在这样的操作中是否有什么我需要担心的,或者我是否可以让 C 在幕后智能地完成所有事情。

【问题讨论】:

  • 这是一种非常糟糕的思维方式。将整数与浮点数混合会导致严重的性能损失。尽可能避免它。

标签: c


【解决方案1】:

当使用浮点数和整数进行算术运算时,它总是将其强制为浮点数。也就是说:

  • float*float = 浮动
  • float*int = 浮点数
  • int*float = 浮点数
  • int*int=int

如果所有值都是整数,您只会收到“整数数学”。

【讨论】:

  • 这个答案有点误导。您应该将“float”替换为“double”。在 C 中没有提升浮动的东西。
  • 有。这些被称为“通常的算术转换”。这篇文章中的整数将被转换为浮点数,而不是双精度数。参见 ISO 9899:1999 6.3.1.8。
【解决方案2】:

这可能有点难看。编译器查看 single 操作的操作数类型,并将两者提升为“更大”类型(例如,如果一个是 int 和另一个 double,它将转换将int转为double,然后进行操作)。

在您的情况下,这可能会产生一些相当出乎意料的结果。现在你有:2*pi*j*X*Y/n。运算符从左到右分组,所以这相当于((((2*pi)*j)*X)*Y)/n。在这种情况下,这可能会很好地解决 - “第一个”操作中的一个操作数是浮点数,因此所有其他操作数都将根据需要转换为浮点数。但是,如果您重新排列操作数(即使以在普通数学中看起来等效的方式),结果可能会完全不同。例如,如果您将其重新排列为 2*Y/n*pi*j*X,则 2*Y/n 部分将使用 integer 算法完成,因为 2Yn 都是整数。这意味着将在整数上进行除法,给出整数结果,并且只有在获得整数结果之后将该整数转换为浮点数以用于乘以pi

底线:除非您正在处理大型数组之类的东西,因此转换为较小的类型可能会真正节省相当多的内存,如果可能,您通常最好保留相同类型的所有操作数.我还要注意,在这种情况下,您尝试“智能管理内存”可能不会有任何好处——在典型的当前机器上,long intfloat 都是 32 位,所以它们在任何情况下,两者都使用相同数量的内存。另请注意,expdouble 作为其操作数,因此即使您对其余部分进行 float 数学运算,它也将被提升为 double。另请注意,从intfloat(以及返回)的转换可能相当缓慢。

如果您真的只处理大约六个变量,那么您几乎可以肯定最好将它们保留为 double 并完成它。转换为 floatlong 的组合将节省大约 14 个字节的数据存储空间,但随后会添加(大约)14 个字节的额外指令来处理 intfloatdouble 之间的所有转换在正确的时间,所以你最终会得到更慢的代码,但无论如何都会使用同样多的内存。

【讨论】:

  • 非常有趣的回复,非常感谢。我认为我通过仔细选择 int 和 floats 来帮助事情。好的,所以似乎共识是将所有内容保持为 64b 精度的两倍,或者保持 32 位精度的所有浮点数。听起来对吗?
  • @gkmath:是的,在这种情况下,我可能会把它们留作双打。
  • "运算符从左到右分组,所以这相当于 ((((2*pi)*j)*X)*Y)/n"。这不是真的,评估的顺序是实现定义的,取决于编译器。编译器还不如从右到左计算表达式,然后你可能会得到完全不同的提升。无论计算顺序如何,程序员都必须确保操作数的类型相同。
  • @Lundin:虽然评估顺序是定义的,但这并不重要——分组定义的(“从左边开始的组to right" 直接来自标准的 §5.6/1),促销是基于分组,不是按评估顺序。
【解决方案3】:

C 语言中的“常用算术转换”在浮点数上的工作方式如下:

  • 如果两个操作数属于同一类型,则一切正常。
  • 如果一个是双精度的,另一个将转换为双精度。
  • 否则,如果一个是浮点数,另一个将转换为浮点数。
  • 否则,如果它们都是整数,则适用“整数提升”的各种规则。

数字常量“1”被视为int。 数字常量“1.0”被视为双精度数。 数字常量“1.0f”被视为浮点数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 2018-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多