保留顺序时将浮点转换为unsigned int

时间:2018-09-17 14:59:05

标签: c floating-point ieee-754

我发现有很多关于SO的答案,重点是将 events: { drilldown: function(e) { var drilldownseries = [{ "name": 'Headcount', "id": 'levelA2', "data": [...] }, { "name": 'Headcount', "id": 'levelA2', "data": [...] } ] if (!e.seriesOptions) { chart.addSingleSeriesAsDrilldown(e.point, drilldownseries[0]); chart.addSingleSeriesAsDrilldown(e.point, drilldownseries[1]); chart.applyDrilldown(); } } } 转换为float

我只处理正浮点值。 我一直在使用的一种简单方法是:

int

上面的代码运行良好,但是无法保留数字顺序。 按顺序我的意思是:

unsigned int float2ui(float arg0) {
    float f = arg0;
    unsigned int r = *(unsigned int*)&f;
    return r;
}

我尝试使用具有相同结果的联合。 任何想法? 我使用Homebrew gcc 5.3.0。

3 个答案:

答案 0 :(得分:4)

您所编写的代码具有未定义的行为。如果您想半便携式地访问float的表示形式(实现定义,定义良好并假定IEEE 754,并且float和integer字节序匹配),则应该执行以下操作:

uint32_t float2ui(float f){
    uint32_t r;
    memcpy(&r, &f, sizeof r);
    return r;
}

对于非负值,浮点值和表示形式之间的映射保留顺序。如果您认为自己无法保留订单,则需要准确查看您认为哪些值是反例。

答案 1 :(得分:3)

如果f1f2是浮点,并且f1 <= f2(int)f1(int)f2是有效的转换,则(int)f1 <= (int)f2。 / p>

换句话说,截断为整数类型从不会交换订单回合。

在检查float2ui(int)arg0的边界内之后,可以用float替换int

请注意,如果floatint floatunsigned的行为未定义float的值超出了类型的范围。

您当前的代码-以某种方式将float内存解释为int内存-具有 undefined 行为。甚至通过union进行类型修饰都会给您实现定义的结果。请特别注意sizeof(int)sizeof(float)不一定相同。

如果,您使用的是IEEE754单精度float,没有陷阱表示的32位2补码int,用于转换的正值,一致的字节序和对于NaN+-Inf所表示的各种模式留有一定的余量,那么类型pun 所实现的转换就是保留顺序。

答案 2 :(得分:0)

使用联合从浮点数中提取位应该可行。如果c标准实际上支持这一点,则有一些讨论。但是不管标准怎么说,gcc似乎都支持它。而且我希望现有的代码过多,编译器才能删除支持。

将浮点数设置为int并保持顺序时,您必须了解一些事情。

  1. public class MyController : Controller { private readonly IUrlHelperFactory factory; //...other dependencies public MyController(IUrlHelperFactory factory) { this.factory = factory; //...other dependencies } public IActionResult GetAll() { var urlHelper = factory.GetUrlHelper(ControllerContext); var nextLink = urlHelper.Link("GetPosts", new { page = 1, pageSize = 3 }); return Ok(new { NextPageLink = nextLink, Results = _context.Posts, test = ControllerContext.RouteData.Values }); } //...other actions } 之类的有趣值没有任何保留顺序
  2. nan存储为幅度和符号位,而floats为二进制补码  (假设一个理智的架构)。因此,对于负值,您必须翻转所有  除符号位以外的其他位
  3. 如果intsfloat在您的体系结构上具有不同的首尾性,则您 还必须转换字节序

这是我的实现,已通过int在x64上进行了测试

gcc (Gentoo 6.4.0-r1 p1.3) 6.4.0