且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C#十进制,如何添加尾随零

更新时间:2023-11-30 11:15:04

A decimal占用128位(16字节),其中1位用于符号,96位(12字节)用于实际符号.值和5位用于存储小数点的位置.

A decimal occupies 128 bits (16 bytes), of which 1 bit is used for the sign, 96 bits (12 bytes) are used for the actual value and 5 bits are used to store the position of the decimal point.

当C#编译器看到1M时,它将解析为{sign: 0, value: 1, point: 0},而将1.0M解析为{sign: 0, value: 10, point: 1}.但是,两者都表示相同的值(1M == 1.0M返回true),并且另一个解析器可以轻松地将1M1.0M都映射到{sign: 0, value: 1, point: 0}.

When the C# compiler sees 1M, it parses it as {sign: 0, value: 1, point: 0}, while 1.0M is parsed as {sign: 0, value: 10, point: 1}. However, both represent the same value (1M == 1.0M returns true), and another parser could easily have mapped both 1M and 1.0M to {sign: 0, value: 1, point: 0}.

1M0.1M一起添加会发生什么? 1M{sign: 0, value: 1, point: 0}0.1M{sign: 0, value: 1, point: 1},因此我们有两个精度不同的数字.但是,这没问题:我们可以通过在1M中的点上添加1并将其值乘以10:{sign: 0, value: 10, point: 1}来移动该点.现在两个数字都具有相同的点位置,我们可以通过简单地将它们的值相加来将它们加在一起,从而得到{sign: 0, value: 11, point: 1},它对应于1.1M.

What happens when you add 1M and 0.1M together? 1M is {sign: 0, value: 1, point: 0} and 0.1M is {sign: 0, value: 1, point: 1}, so we have two numbers with different precision. That's no problem however: we can move the point in 1M by adding 1 to its point and by multiplying its value by 10: {sign: 0, value: 10, point: 1}. Now that both numbers have the same point position, we can add them together by simply adding up their values, which results in {sign: 0, value: 11, point: 1}, which corresponds to 1.1M.

因此decimal的内部表示形式不会影响其操作的精度-只要有必要,小数点位置都会移动(并调整值).*

So the internal representation of a decimal does not affect the precision of its operations - the decimal point position is moved (and the value adjusted) whenever this becomes necessary.*

但是,如果由于某种原因您的小数位绝对必须具有一定的位置(从您到目前为止发布的内容来看,我没有令人信服的理由-格式纯粹是显示问题),那么最简单的方法是使用decimal(int, int, int, bool, byte)构造函数(或替换为decimal(int[])).这使您可以传入值(作为3个整数),符号(作为布尔值)和点位置(作为字节).如果传递的点位置高于0,则必须自己乘以该值:1.000M必须构造为new decimal(1000, 0, 0, false, 3),而不是new decimal(1, 0, 0, false, 3)(因为这样会得到0.001M).

However, if for some reason your decimals absolutely must have a certain point position (and from what you've posted so far, I see no compelling reason - formatting is purely a display issue), then the easiest approach is to use the decimal(int, int, int, bool, byte) constructor (or alternately decimal(int[])). This allows you to pass in the value (as 3 integers), the sign (as a boolean) and the point position (as a byte). You will have to multiply the value yourself if you pass a point position higher than 0: 1.000M must be constructed as new decimal(1000, 0, 0, false, 3), not as new decimal(1, 0, 0, false, 3) (because that would give you 0.001M).

*点的位置限制为[0-28],因此decimal不能表示点后超过28位的数字.同样,该值必须在点前面和点后面的数字之间分割",因此,非常大的数字将限制可用精度,可能会降低它的大小,以表示点前面的数字.

*the point position is limited to [0-28], so a decimal cannot represent numbers with more than 28 digits behind the dot. Also, the value has to be 'split' between digits in front of the dot and behind the dot, so very large numbers will put restrictions on the available precision, possibly cutting it down in favor of representing the digits in front of the dot.