簡體   English   中英

Go:使用乘數將float64轉換為int

[英]Go: Converting float64 to int with multiplier

我想轉換一個float64號碼,比方說1.0031003 (整數類型)。 我的實現只是將float641000相乘並將其轉換為int

package main

import "fmt"


func main() {
  var f float64 = 1.003
  fmt.Println(int(f * 1000))
}

但是當我運行該代碼時,我得到的是1002而不是1003 因為Go會自動將1.003存儲為1.002999...在變量中。 在Golang上進行這種操作的正確方法是什么?

轉到規格:轉換:

數字類型之間的轉換

將浮點數轉換為整數時,將丟棄該分數(截斷為零)。

所以基本上當你將浮點數轉換為整數時,只保留整數部分。

如果您只是想避免因使用有限位表示而產生的錯誤,只需在將數字轉換為int之前將數字加0.5即可。 無需外部庫或函數調用(來自標准庫)。

由於float -> int轉換不是舍入而是保留整數部分 ,因此這將為您提供所需的結果。 考慮到可能的更小和更大的代表性:

1002.9999 + 0.5 = 1003.4999;     integer part: 1003
1003.0001 + 0.5 = 1003.5001;     integer part: 1003

所以簡單地寫一下:

var f float64 = 1.003
fmt.Println(int(f * 1000 + 0.5))

將它包裝成一個函數:

func toint(f float64) int {
    return int(f + 0.5)
}

// Using it:
fmt.Println(toint(f * 1000))

Go Playground上試試

注意:

如果是負數,請小心使用! 例如,如果您的值為-1.003 ,那么您可能希望結果為-1003 但是如果你加0.5

-1002.9999 + 0.5 = -1002.4999;     integer part: -1002
-1003.0001 + 0.5 = -1002.5001;     integer part: -1002

因此,如果您有負數,則必須:

  • 減去0.5而不是添加它
  • 或者添加0.5但從結果中減去1

將此結合到我們的輔助函數中:

func toint(f float64) int {
    if f < 0 {
        return int(f - 0.5)
    }
    return int(f + 0.5)
}

正如威爾所提到的,這歸結為浮動在各種平台上的表現方式。 基本上你需要對浮點數進行舍入而不是讓默認的截斷行為發生。 這沒有標准的庫函數,可能是因為有很多可能的行為,實現起來很簡單。

如果你知道你總是有所描述類型的錯誤,你所需的值(130099000)略低於(1299.999999)你可以使用數學庫的Ceil函數:

f := 1.29999
n := math.Ceil(f*1000)

但是,如果您有不同類型的浮動錯誤並想要更通用的排序行為? 使用數學庫的Modf函數將浮點值與小數點分開:

f := 1.29999

f1,f2 := math.Modf(f*1000)
n := int(f1) // n = 1299   
if f2 > .5 { 
    n++
}
fmt.Println(n)

您可以自己在游樂場中運行此代碼的稍微更通用的版本。

在大多數編程語言中,這通常可能是浮點問題,盡管有些實現與其他編程語言不同。 我不會在這里討論復雜的問題,但是大多數語言通常采用“十進制”方法作為標准庫或第三方庫來獲得更精確的。

例如,我發現inf.v0包非常有用。 該庫的底層是一個Dec結構,它包含指數和整數值。 因此,它能夠將1.003保持為1003 * 10^-3 請參閱下面的示例:

package main

import (
    "fmt"

    "gopkg.in/inf.v0"
)

func main() {
    // represents 1003 * 10^-3
    someDec := inf.NewDec(1003, 3)

    // multiply someDec by 1000 * 10^0
    // which translates to 1003 * 10^-3 * 1000 * 10^0
    someDec.Mul(someDec, inf.NewDec(1000, 0))

    // inf.RoundHalfUp rounds half up in the 0th scale, eg. 0.5 rounds to 1
    value, ok := someDec.Round(someDec, 0, inf.RoundHalfUp).Unscaled()
    fmt.Println(value, ok)
}

希望這可以幫助!

暫無
暫無

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

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