加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C#decimal,如何添加尾随零

发布时间:2020-12-16 09:55:22 所属栏目:百科 来源:网络整理
导读:我必须将尾随零添加到十进制值.不仅用于显示(因此Format不是一个选项),而是在实际的底层数据中,因为小数精度在我们的应用程序中很重要. 我试过了: decimal value = 1Mdecimal withPrecision = value + 0.000M; 在许多情况下哪种方法效果很好……奇怪的是并
我必须将尾随零添加到十进制值.不仅用于显示(因此Format不是一个选项),而是在实际的底层数据中,因为小数精度在我们的应用程序中很重要.

我试过了:

decimal value = 1M
decimal withPrecision = value + 0.000M;

在许多情况下哪种方法效果很好……奇怪的是并非总体而言.我调试了一个情况,其中withPrecision中的值仍然是1M,没有看到运行时的值和立即窗口中相同的硬编码值有任何差异.我还使用了decimal.GetBits来找到差异 – 没有.

我试过(这里建议Adjusting decimal precision,.net):

decimal value = 1M
decimal withPrecision = value * 1.000M;

效果很好 – 除了案例值为零.然后结果为0M,没有任何尾随零.我也不相信解决方案,在其他情况下也可能不起作用.

目前我在:

decimal value = 1M
decimal withPrecision = (value * 1.000M) + 0.000M;

这在我目前发现的所有情况下都有效……但是看起来也不值得信赖.我还可以为零实现一个例外情况.

我认为Format和Parse会起作用.我不喜欢它.它看起来不是很快,我不明白为什么我必须将小数字放入一个字符串只是为了操纵它.

我开始相信这样一个简单的任务没有干净的解决方案.

解决方法

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

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

将1M和0.1M加在一起会发生什么? 1M是{sign:0,0.1M是{sign:0,point:1},所以我们有两个精度不同的数字.然而,这没有问题:我们可以通过在其点加1并将其值乘以10来移动1M点:{符号:0,值:10,点:1}.现在两个数字具有相同的点位置,我们可以通过简单地将它们的值相加来将它们加在一起,这导致{sign:0,value:11,这对应于1.1M.

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

但是,如果由于某种原因你的小数绝对必须有一个点位置(并且从你到目前为止发布的,我看到没有令人信服的理由 – 格式化纯粹是显示问题),那么最简单的方法是使用小数( int,int,bool,byte)构造函数(或者十进制(int [])).这允许您传入值(作为3个整数),符号(作为布尔值)和点位置(作为字节).如果传递高于0的点位置,则必须自己乘以该值:1.000M必须构造为新的十进制(1000,false,3),而不是新的十进制(1,false),3)(因为那会给你0.001M).

*点位置限制为[0-28],因此小数不能表示点后面超过28位的数字.此外,该值必须在点前面和点后面的数字之间“分开”,因此非常大的数字会对可用精度施加限制,可能会将其缩小以支持在点前面表示数字.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读