用整数计算浮点数的标准化方法是什么? [英] How is the standarized way to calculate float with integers?

查看:39
本文介绍了用整数计算浮点数的标准化方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你们有谁知道这将如何在 C 中计算?

uint8_t 采样率 = 200;uint8_t 结果;结果 = 0.5 * 采样率;

现在,问题是 0.5 是一个浮点数,而 samplerate 是一个整数.Result 然后可以是 0,因为 0.5 被转换为整数,因此四舍五入为 0(Result = 0 * 200 = 0).或者 Result 可能是 100,因为编译器首先看到 0.5 并将 samplerate 转换为浮点数(Result = 0.5 * 200 = 100).>

编译器将如何处理这些计算是否有标准化的方法?我的意思是编译器会先查看最左边的变量(在本例中为 0.5)并将另一个转换为这个,还是会查看最右边的变量(samplerate)并转换其他变量呢?

我知道如何解决这个问题,但我在寻找一个通用的答案,如果这是 C 标准化的,它将如何计算这样的方程?

解决方案

当各种类型的数值组合在一个表达式中时,它们会受到通常的算术转换,这是一组规定应转换哪个操作数以及转换为何种类型的规则.

C 标准的第 6.3.1.8 节详细说明了这些转换:

<块引用>

许多期望算术类型操作数的运算符导致以类似的方式转换和产生结果类型.目的是确定操作数和结果的公共实数类型.为了指定的操作数,每个操作数都被转换,不改变类型域,到一个类型,其对应的真实类型是普通实型.除非另有明确说明,否则普通实型也是对应的实型结果,其类型域是操作数的类型域如果它们相同,否则复杂.这个图案是称为通常的算术转换:

  • 首先,如果任一操作数的对应实数类型为 long double ,则将另一个操作数在不改变类型域的情况下转换为对应实数类型为 long 的类型双重.
  • 否则,如果任一操作数的对应实数类型为 double ,则另一个操作数将在不改变类型域的情况下转换为对应实数类型为双重.
  • 否则,如果任一操作数的对应实数类型为 float ,则另一个操作数将在不改变类型域的情况下转换为对应实数类型为浮动.
  • 否则,将在两个操作数上执行整数提升.然后将以下规则应用于提升的操作数:
    • 如果两个操作数的类型相同,则不再需要转换.
    • 否则,如果两个操作数都已签名整数类型或两者都有无符号整数类型,操作数与较小整数转换等级的类型转换到更高等级的操作数的类型.
    • 否则,如果具有无符号整数类型的操作数具有更高的等级或等于另一个操作数的类型的等级,然后带符号整数类型的操作数被转换为类型无符号整数类型的操作数.
    • 否则,如果带符号整数类型的操作数的类型可以表示所有的具有无符号整数类型的操作数类型的值,然后无符号整数类型的操作数被转换为类型带符号整数类型的操作数.
    • 否则,两个操作数都被转换为无符号整数类型对应有符号整数类型的操作数的类型.

特别注意以粗体显示的段落,这适用于您的情况.

浮点常量0.5的类型为double,所以其他操作数的值转换为double类型,结果为乘法运算符 * 的类型为 double.然后将此结果赋值回 uint8_t 类型的变量,因此 double 值将转换为该类型以进行赋值.

所以在这种情况下 Result 的值为 100.

Do any of you know how this will be calculated in C?

uint8_t samplerate = 200;
uint8_t Result;
Result = 0.5 * samplerate;

Now, the problem is that 0.5 is a float and samplerate an integer. Result could then be either 0, because 0.5 is converted in an integer and therefore rounded to 0 (Result = 0 * 200 = 0). Or Result could be 100, because the compiler sees 0.5 first and converts samplerate into float (Result = 0.5 * 200 = 100).

Is there a standarized way how the compiler will handle these calculations? I mean will the compiler look at the variable on the very left (in this case 0.5) first and convert the other to this, or will it look at the variable on the very right (samplerate) and convert the other variables to this?

I know how I could solve this problem but I look for an general answer, if this is C standarized and how will it calculate such equations?

解决方案

When numeric values of various types are combined in a expression, they are subject to the usual arithmetic conversions, which is a set of rules which dictate which operand should be converted and to what type.

These conversions are spelled out in section 6.3.1.8 of the C standard:

Many operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to determine a common real type for the operands and result. For the specified operands, each operand is converted, without change of type domain, to a type whose corresponding real type is the common real type. Unless explicitly stated otherwise, the common real type is also the corresponding real type of the result, whose type domain is the type domain of the operands if they are the same, and complex otherwise. This pattern is called the usual arithmetic conversions :

  • First, if the corresponding real type of either operand is long double , the other operand is converted, without change of type domain, to a type whose corresponding real type is long double .
  • Otherwise, if the corresponding real type of either operand is double , the other operand is converted, without change of type domain, to a type whose corresponding real type is double .
  • Otherwise, if the corresponding real type of either operand is float , the other operand is converted, without change of type domain, to a type whose corresponding real type is float .
  • Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:
    • If both operands have the same type, then no further conversion is needed.
    • Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
    • Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
    • Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.
    • Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.

Note in particular the paragraph in bold, which is what applies in your case.

The floating point constant 0.5 has type double, so the value of other operand is converted to type double, and the result of the multiplication operator * has type double. This result is then assigned back to a variable of type uint8_t, so the double value is converted to this type for assignment.

So in this case Result will have the value 100.

这篇关于用整数计算浮点数的标准化方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆