簡體   English   中英

Ubuntu 64位上的單精度浮點數表示不正確

[英]Incorrect single precision floating point representation on ubuntu 64 bit

我有以下數據。

float u[4] = {0x3f951d32, 0x3f207887, 0x3d99c3a0, 0x3eb405d2};
ScaleFunction(u);

void ScaleFunction(float *u_ptr)
{
  for(int i = 0; i < 4; i++)
  {
    printf("u[%d] = %f\n", u_ptr[i]);
  }
  // And a lot more
}

包含上述代碼段的應用程序在運行ubuntu 16.10的64位計算機上執行。

令我煩惱的是,浮點數被錯誤地解釋為:1066736960.000000,1059092608.000000,1033487232.000000和1051985344.000000。

當數字以十六進制打印時,確認呼叫者將正確的值傳遞給被呼叫者。

我在這里做錯了什么?

我什至沒有高興地嘗試了以下方法。

uint32_t u[4] = {0x3f951d32, 0x3f207887, 0x3d99c3a0, 0x3eb405d2};
ScaleFunction(u);

void ScaleFunction(uint32_t *u_ptr)
{
  float ut[4];
  for(int i = 0; i < 4; i++)
  {
    ut[i] = (float) u_ptr[i];
    printf("ut[%d] = %f\n", ut[i]);
  }
  // And a lot more
}

我希望將被調用方中的十六進制解釋為:1.1649、0.6268、0.075、0.5516

問題是,您使用大整數值而不是浮點數的十六進制表示來初始化數組。 十六進制常數以0x3f左右的值開頭,因此很明顯,它們是1.0左右的浮點數據。

據我所知,沒有直接方法用十六進制常量初始化浮點數組(如果有的話,請告訴我!)。

因此,您必須將數據數組定義為int,並在使用時將其轉換為float。 重要說明:將指針直接從int轉換為float將破壞C的別名規則,並可能導致看起來正確但行為不當的代碼。

通過memcpy在兩種數據類型之間進行轉換是安全的,並且編譯器通常足夠聰明以發現並優化它。

因此,此解決方案可以滿足您的需求:

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

uint32_t u[4] = {0x3f951d32, 0x3f207887, 0x3d99c3a0, 0x3eb405d2};

void ScaleFunction(uint32_t *u_ptr)
{
  for(int i = 0; i < 4; i++)
  {
      float temp;
      memcpy (&temp, &u[i], sizeof (float));
      printf("u[%d] = %f\n", i, temp);
  }
  // And a lot more
}


void main (int argc, char **args)
{
  ScaleFunction (u);
}

您的代碼無法按照您的想法工作:您正在為浮點數分配整數。 您未將十六進制值分配為浮點數。

最好的辦法是擁有一個初始化數組並將其復制到您的float數組中

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

uint32_t init[] = {0x3f951d32u, 0x3f207887u, 0x3d99c3a0u, 0x3eb405d2u};

void ScaleFunction(float *u_ptr, size_t size)
{
  for(size_t i = 0; i < size; i++)
  {
    printf("u[%zu] = %f\n", i, u_ptr[i]);
  }
  // And a lot more
}

int main (void)
{
    assert ( sizeof(float) == sizeof(uint32_t) );

    float u[sizeof(init)/sizeof(init[0])];

    memcpy(u, init, sizeof(init));

    ScaleFunction(u, sizeof(init)/sizeof(init[0]));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM