比较uint64_t和float的数值等效性 [英] Comparing uint64_t and float for numeric equivalence

查看:293
本文介绍了比较uint64_t和float的数值等效性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个协议,该协议使用 RFC 7049 作为其二进制表示形式.该标准规定,如果协议的数值等于相应的64位数字,则该协议可以使用32位浮点数表示.转换一定不会导致精度下降.

I am writing a protocol, that uses RFC 7049 as its binary representation. The standard states, that the protocol may use 32-bit floating point representation of numbers, if their numeric value is equivalent to respective 64-bit numbers. The conversion must not lead to lose of precision.

  • 哪些32位浮点数可以大于64位整数并在数值上等效于它们?
  • 比较float x; uint64_t y; (float)x == (float)y是否足以确保值相等?这种比较会正确吗?
  • What 32-bit float numbers can be bigger than 64-bit integer and numerically equivalent with them?
  • Is comparing float x; uint64_t y; (float)x == (float)y enough for ensuring, that the values are equivalent? Will this comparison ever be true?

RFC 7049§3.6.数字

出于本规范的目的,所有数字表示形式 相同的数值是等效的.这意味着 编码器可以将0.0的浮点值编码为整数0. 但是,这也意味着希望找到一个应用程序. 如果编码器,则整数值只能找到浮点值 决定这些值是理想的,例如当浮点值是 比64位整数更紧凑.

For the purposes of this specification, all number representations for the same numeric value are equivalent. This means that an encoder can encode a floating-point value of 0.0 as the integer 0. It, however, also means that an application that expects to find integer values only might find floating-point values if the encoder decides these are desirable, such as when the floating-point value is more compact than a 64-bit integer.

推荐答案

以下内容基于

The following is based on Julia's method for comparing floats and integers. This does not require access to 80-bit long doubles or floating point exceptions, and should work under any rounding mode. I believe this should work for any C float type (IEEE754 or not), and not cause any undefined behaviour.

更新:从技术上讲,它假定二进制float格式,并且float指数大小足够大,可以表示2 64 :对于标准IEEE754 binary32(您确实可以使用它)请参阅您的问题),但不是,例如binary16.

UPDATE: technically this assumes a binary float format, and that the float exponent size is large enough to represent 264: this is certainly true for the standard IEEE754 binary32 (which you refer to in your question), but not, say, binary16.

#include <stdio.h>
#include <stdint.h>

int cmp_flt_uint64(float x,uint64_t y) {
  return (x == (float)y) && (x != 0x1p64f) && ((uint64_t)x == y);
}

int main() {
  float x = 0x1p64f;
  uint64_t y = 0xffffffffffffffff;

  if (cmp_flt_uint64(x,y))
    printf("true\n");
  else 
    printf("false\n");
  ;
}

这里的逻辑如下:

  • 仅当x是区间[0,2 64 ]中的非负整数时,第一个等式才可以成立.
  • 第二个检查x(因此是(float)y)不是2 64 :如果是这种情况,则y不能由float精确表示,并且所以比较是错误的.
  • x的任何剩余值都可以精确转换为uint64_t,因此我们进行了比较.
  • The first equality can be true only if x is a non-negative integer in the interval [0,264].
  • The second checks that x (and hence (float)y) is not 264: if this is the case, then y cannot be represented exactly by a float, and so the comparison is false.
  • Any remaining values of x can be exactly converted to a uint64_t, and so we cast and compare.

这篇关于比较uint64_t和float的数值等效性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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