当前位置: 首页 > 面试题库 >

IEEE 754二进制浮点数不精确

仲法
2023-03-14
问题内容

math.Floor与浮点变量一起使用时出现问题(向下舍入/截断精度部分)。如何正确执行

package main

import (
    "fmt"
    "math"
)

func main() {
    var st float64 = 1980
    var salePrice1 = st * 0.1 / 1.1
    fmt.Printf("%T:%v\n", salePrice1, salePrice1) // 179.9999
    var salePrice2 = math.Floor(st * 0.1 / 1.1)
    fmt.Printf("%T:%v\n", salePrice2, salePrice2) // 179
}

游乐场:https :
//play.golang.org/p/49TjJwwEdEJ

输出:

float64:179.99999999999997
float64:179

我期望的输出1980 * 0.1 / 1.1180的,但实际产量179


问题答案:

原始问题:

Golang中的楼层号不正确

将Math.Floor与float变量一起使用时出现问题(向下舍入/截断精度部分)。我该怎么做呢?

package main

import (
    "fmt"
    "math"
)

func main() {
    var st float64 = 1980
    var salePrice1 = st * 0.1 / 1.1
    fmt.Printf("%T:%v\n", salePrice1, salePrice1)
    var salePrice2 = math.Floor(st * 0.1 / 1.1)
    fmt.Printf("%T:%v\n", salePrice2, salePrice2)
}

我预计1980 * 0.1 / 1.1的输出为180,但实际输出为179。”

操场:

输出:

float64:179.99999999999997
float64:179

XY问题是在询问您尝试的解决方案,而不是实际问题:XY问题。

显然,这是的货币计算salePrice1。货币计算使用精确的十进制计算,而不是不精确的二进制浮点计算。

对于货币计算,请使用整数。例如,

package main

import "fmt"

func main() {
    var st int64 = 198000 // $1980.00 as cents

    fmt.Printf("%[1]T:%[1]v\n", st)
    fmt.Printf("$%d.%02d\n", st/100, st%100)

    var n, d int64 = 1, 11
    fmt.Printf("%d, %d\n", n, d)

    var salePrice1 int64 = (st * n) / d // round down

    fmt.Printf("%[1]T:%[1]v\n", salePrice1)
    fmt.Printf("$%d.%02d\n", salePrice1/100, salePrice1%100)

    var salePrice2 int64 = ((st*n)*10/d + 5) / 10 // round half up

    fmt.Printf("%[1]T:%[1]v\n", salePrice2)
    fmt.Printf("$%d.%02d\n", salePrice2/100, salePrice2%100)

    var salePrice3 int64 = (st*n + (d - 1)) / d // round up

    fmt.Printf("%[1]T:%[1]v\n", salePrice1)
    fmt.Printf("$%d.%02d\n", salePrice3/100, salePrice3%100)
}

游乐场:https :
//play.golang.org/p/HbqVJUXXR-N

输出:

int64:198000
$1980.00
1, 11
int64:18000
$180.00
int64:18000
$180.00
int64:18000
$180.00

参考文献:

每个计算机科学家都应了解的浮点运算法则
通用十进制算术



 类似资料:
  • 问题内容: 为什么单精度浮点数具有7位精度(或双精度15-16位精度)? 谁能解释一下如何根据为float(Sign(32)Exponent(30-23),Fraction(22-0))分配的32位来达到这个目标? 问题答案: 有效位的23个小数位(22-0)出现在内存格式中,但是总精度实际上是24位,因为我们假设有一个前导1。这等效于十进制数字。 双精度浮点数的分数为52位,加上前导1为53。因

  • 假设我使用一个32位的浮点数来存储一个位串(不要问)。进一步假设我想将这个浮点数序列化为一个文件(作为一个浮点数),并在序列化之前对浮点数的十进制表示进行银行家四舍五入。当我将浮点数读回程序时,系统会(自然地)将其存储在一个32位的浮点数中,该浮点数尽可能接近序列化的数字。 在银行舍入后,我的序列化浮点数在数字上必须有多精确,才能确保序列化的浮点数在二进制上与读回的浮点数相等?

  • 本文向大家介绍C#浮点,双精度,十进制,包括了C#浮点,双精度,十进制的使用技巧和注意事项,需要的朋友参考一下 示例 浮动 float是.NET数据类型的别名System.Single。它允许存储IEEE 754单精度浮点数。存在此数据类型mscorlib.dll,每个C#项目在创建它们时都会隐式引用该数据类型。 大致范围:-3.4×10 38至3.4×10 38 十进制精度:6-9个有效数字 记

  • 浮点是C语言中定义的实现,因此没有任何保证。 我们的代码需要可移植,我们正在讨论是否可以在协议中使用IEEE754浮动。出于性能考虑,如果我们在发送或接收数据时不必在定点格式之间来回转换,那就太好了。 虽然我知道平台和架构之间在或的大小上可能存在差异。但我似乎找不到任何关于和的具体信息。 到目前为止,我发现在big endian平台上字节顺序可能会颠倒。虽然有些平台不支持浮点运算,但包含和的代码甚

  • 问题内容: $a = ‘35’; $b = ‘-34.99’; echo ($a + $b); 结果为0.009999999999998 这是怎么回事?我想知道为什么我的程序不断报告奇怪的结果。 为什么PHP不返回预期的0.01? 问题答案: 因为浮点运算!=实数运算。对于一些浮子和,由不精确性引起的差异的说明是。这适用于使用浮点数的任何语言。 由于浮点数是具有有限精度的二进制数,因此存在有限数量