相除和取模有什么区别?
相除和取模是两种不同的数学运算。
相除(除法)是指将一个数除以另一个数,得到商的过程。例如,10除以3,商为3,余数为1。在数学中,除法通常使用符号 / 表示。
取模(取余)是指将一个数除以另一个数,得到余数的过程。例如,10除以3,余数为1。在数学中,取模通常使用符号 % 表示。
在编程中,相除和取模运算经常用于处理整数类型的数据。
例如,在计算机编程中,可以使用相除运算来计算两个数的商,而使用取模运算来计算两个数的余数。
以下是一个示例:
1 2 3 4 5 6 7 8 a = 10 b = 3 quotient = a / b remainder = a % b print ("商:" , quotient) print ("余数:" , remainder)
在上述示例中,a / b 进行相除运算得到商,结果为3.3333333333333335,即10除以3的浮点数商。a % b 进行取模运算得到余数,结果为1,即10除以3的余数。
需要注意的是,相除运算的结果可能是浮点数(如上述示例中的商),而取模运算的结果总是整数。取模运算的结果与被除数的符号相同。
总结:
相除运算是计算除法的商,结果可能是浮点数。
取模运算是计算除法的余数,结果总是整数。
golang这为什么相除不会出现小数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package mainimport ( "fmt" ) func main () { fmt.Println(1 / 2 ) fmt.Println(11 / 5 ) fmt.Println(11 % 5 ) }
1 2 3 4 5 6 7 8 9 10 11 12 13 package mainimport "fmt" func main () { a := 12 b := 5 quotient := float64 (a) / float64 (b) fmt.Println("商:" , quotient) }
在 Go 语言中,整数之间的相除运算结果会被截断为整数,不会保留小数部分。这是因为在整数之间进行除法运算时,Go 语言会对结果进行向零取整(向下取整)的操作,返回一个整数结果。
如果你想要得到浮点数的结果,可以将其中一个操作数转换为浮点数类型,这样整数除以浮点数的运算会得到浮点数结果。
以下是一个示例:
1 2 3 4 5 6 7 8 9 10 11 package mainimport "fmt" func main () { a := 10 b := 3 quotient := float64 (a) / float64 (b) fmt.Println("商:" , quotient) }
在上述示例中,通过使用 float64(a) 和 float64(b) 将操作数转换为浮点数类型,然后进行相除运算,得到了浮点数商。最后使用 fmt.Println 输出了结果。
需要注意的是,如果参与相除运算的两个操作数都是整数类型,则结果仍然是整数类型,即使使用浮点数类型接收也只会截断小数部分。为了得到浮点数的精确结果,至少其中一个操作数需要是浮点数类型。
go是强类型语言啊…..必须显式转换,你想一下,两个int一运算,出来个float??这不合适吧。所以go这种强类型语言会向下截取,不要小数部分
如果是php,是会输出浮点数。 php是动态语言,因为弱类型,和lua,python,erlang一样。我刚才说php会出现这问题,是指的进一法和退一法,四舍五入,比如正常应该是4.7,最后得到的是4还是5,就是 ceil,floor,round
https://blog.csdn.net/lz0426001/article/details/42707599
输出0.5
带着问题出发:
https://floating-point-gui.de/
https://github.com/golang/go/issues/34756
1 2 3 4 5 6 value1 := strconv.FormatFloat(9.815 , 'f' , 2 , 64 ) fmt.Println(value1) value2 := strconv.FormatFloat(9.185 , 'f' , 2 , 64 ) fmt.Println(value2)
为什么会出现这样的情况?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 func FormatFloat (f float64 , fmt byte , prec, bitSize int ) string { return string (genericFtoa(make ([]byte , 0 , max(prec+4 , 24 )), f, fmt, prec, bitSize)) } FormatFloat将浮点数f转换为字符串, 根据格式fmt和precision prec。它四舍五入 假定原始结果是从浮点数获得的结果 bitSize位的值(float32 为32 ,float64 为64 )。 格式fmt是以下格式之一 'b' (-ddddp±ddd,二进制指数), 'e' (-d.dddde±dd,十进制指数), 'E' (-d.ddddE±dd,十进制指数), 'f' (-ddd.dddd,无指数), 'g' (对于大指数而言为'e' ,否则为'f' ), 'G' (对于大指数而言为'E' ,否则为'f' ), 'x' (-0xd .ddddp±ddd,十六进制分数和二进制指数),或 'X' (-0Xd .ddddP±ddd,十六进制分数和二进制指数)。 precision prec控制位数(不包括指数) 以“ e”,“ E”,“ f”,“ g”,“ G”,“ x”和“ X”格式打印。 对于“ e”,“ E”,“ f”,“ x”和“ X”,它是小数点后的位数。 对于“ g”和“ G”,它是有效数字的最大值(后跟 零)。 特殊精度-1 使用最少的位数 以便ParseFloat准确返回f。
FormatFloat四个参数,分别是:
float64类型的待处理值
格式fmt,如果是f表示 无指数
prec,精度,如果传2,即表示保留小数点后2位
bitSize,只能传32或64
max(prec+4, 24)和genericFtoa
简单比较大小.
1 2 3 4 5 6 func max (a, b int ) int { if a > b { return a } return b }
比较传入的(精度值+4),和24的大小,取其中较大者. 即如果小数点后保留的位数小于20,这个值就是24
故而此时 make([]byte, 0, 24),就是初始化一个uint8类型,容量为24的切片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 func genericFtoa (dst []byte , val float64 , fmt byte , prec, bitSize int ) []byte { var bits uint64 var flt *floatInfo print ("传入的待创处理的float64类型的值:" ,val,"\n" ) switch bitSize { case 32 : bits = uint64 (math.Float32bits(float32 (val))) flt = &float32info case 64 : bits = math.Float64bits(val) flt = &float64info default : panic ("strconv: illegal AppendFloat/FormatFloat bitSize" ) } print ("得到的bits的值:" ,bits,"\n" ) neg := bits>>(flt.expbits+flt.mantbits) != 0 exp := int (bits>>flt.mantbits) & (1 <<flt.expbits - 1 ) mant := bits & (uint64 (1 )<<flt.mantbits - 1 ) switch exp { case 1 <<flt.expbits - 1 : var s string switch { case mant != 0 : s = "NaN" case neg: s = "-Inf" default : s = "+Inf" } return append (dst, s...) case 0 : exp++ default : mant |= uint64 (1 ) << flt.mantbits } exp += flt.bias if fmt == 'b' { return fmtB(dst, neg, mant, exp, flt) } if fmt == 'x' || fmt == 'X' { return fmtX(dst, prec, fmt, neg, mant, exp, flt) } if !optimize { return bigFtoa(dst, prec, fmt, neg, mant, exp, flt) } var digs decimalSlice ok := false shortest := prec < 0 if shortest { f := new (extFloat) lower, upper := f.AssignComputeBounds(mant, exp, neg, flt) var buf [32 ]byte digs.d = buf[:] ok = f.ShortestDecimal(&digs, &lower, &upper) if !ok { return bigFtoa(dst, prec, fmt, neg, mant, exp, flt) } switch fmt { case 'e' , 'E' : prec = max(digs.nd-1 , 0 ) case 'f' : prec = max(digs.nd-digs.dp, 0 ) case 'g' , 'G' : prec = digs.nd } } else if fmt != 'f' { digits := prec switch fmt { case 'e' , 'E' : digits++ case 'g' , 'G' : if prec == 0 { prec = 1 } digits = prec } if digits <= 15 { var buf [24 ]byte digs.d = buf[:] f := extFloat{mant, exp - int (flt.mantbits), neg} ok = f.FixedDecimal(&digs, digits) } } if !ok { return bigFtoa(dst, prec, fmt, neg, mant, exp, flt) } return formatDigits(dst, shortest, neg, digs, prec, fmt) }
20241030
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package mainimport ( "fmt" "log" "math" ) func main () { xchiPrice := 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005 xchiPrice = 0 log.Printf("xICHI price: %.2f" , xchiPrice) xichiRatio := math.Abs(12000000 ) / xchiPrice log.Printf("xichiRatio : %.2f" , xichiRatio) }
1 2 3 2024/10/30 10:50:08 xICHI price: 0.00 2024/10/30 10:50:08 xichiRatio : +Inf +Inf
chiPrice的价格得无限趋近于0才会是+Inf
浮点数的上限非常大,
golang中何时会变为 +Inf 在 Go 语言中,使用 math/big 包或标准的浮点数类型(如 float32 和 float64)时,数值可能会变为 +Inf(正无穷大)在以下几种情况:
1. 除以零 当一个非零的浮点数被零除时,会产生 +Inf:
2. 超出浮点数可表示的最大值 当计算的结果超出了浮点数类型能表示的最大值时,结果会变为 +Inf:
1 2 maxFloat := math.MaxFloat64 result := maxFloat * 2
3. 大数相加 如果两个非常大的浮点数相加,可能也会导致结果溢出,变为 +Inf:
1 2 3 a := math.MaxFloat64 b := math.MaxFloat64 result := a + b
4. 使用 big.Float 时 在使用 math/big 包时,相似的操作也会导致结果为 +Inf:
除以 big.NewFloat(0)。
计算超出 big.Float 可表示的范围。
示例代码 以下是一个简单的示例,演示了如何在 Go 中处理这些情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package mainimport ( "fmt" "math" ) func main () { fmt.Println(1.0 / 0.0 ) fmt.Println(math.MaxFloat64 * 2 ) a := math.MaxFloat64 b := math.MaxFloat64 fmt.Println(a + b) }
注意事项
在进行浮点数计算时,特别是在可能导致溢出的情况下,应该小心处理,并且在必要时进行检查,以避免产生 +Inf。
浮点数可表示的最大值 是多少 在 Go 语言中,浮点数的可表示最大值取决于使用的具体类型。Go 语言主要有两种浮点数类型:float32 和 float64。
1. float32
最大值 :math.MaxFloat32
值 :3.4028235e+38
2. float64
最大值 :math.MaxFloat64
值 :1.7976931348623157e+308
示例代码 你可以使用以下代码来查看这些最大值:
1 2 3 4 5 6 7 8 9 10 11 package mainimport ( "fmt" "math" ) func main () { fmt.Println("Max Float32:" , math.MaxFloat32) fmt.Println("Max Float64:" , math.MaxFloat64) }
总结
float32 的最大值大约为 3.4 × 10^38。
float64 的最大值大约为 1.8 × 10^308。
由于 float64 能表示的范围更广,通常在需要高精度计算时推荐使用 float64。
如果a声明是浮点型,就算是0,也不会panic(有点没想到..)。。但是直接fmt.Println(1 / 0)会 invalid operation: division by zero
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package mainimport ( "fmt" ) func main () { var a float64 a = 0 fmt.Println(1 / a) }
原文链接: https://dashen.tech/2020/12/02/Go源码分析之浮点型处理/
版权声明: 转载请注明出处.