Vb.net 不使用字符串操作的double的小数部分

Vb.net 不使用字符串操作的double的小数部分,vb.net,double,Vb.net,Double,有没有一种方法可以不使用字符串操作就得到一个Double的分数部分?特别是在vb.net中 在各种语言中有许多十进制的例子 基本上,它们似乎都使用mod或Truncate方法,或者利用强制转换为整数的行为。但是,由于双/浮点类型固有的不精确性,这些方法都不适用于双/浮点类型。还有一个问题是,double不能可靠地转换为小数。下面是一个测试用例来说明我的意思和期望 <TestClass> _ Public Class BasicNumberTests Func

有没有一种方法可以不使用字符串操作就得到一个Double的分数部分?特别是在vb.net中

在各种语言中有许多十进制的例子

基本上,它们似乎都使用mod或Truncate方法,或者利用强制转换为整数的行为。但是,由于双/浮点类型固有的不精确性,这些方法都不适用于双/浮点类型。还有一个问题是,double不能可靠地转换为小数。下面是一个测试用例来说明我的意思和期望

<TestClass> _
    Public Class BasicNumberTests

        Function DecimalFractionalPart(ByVal number As Decimal) As Decimal
            Dim wholePart As Decimal = Math.Truncate(number)
            Return number - wholePart
        End Function

        Function DoubleFractionalPart(ByVal number As Double) As Double
            Dim wholePart As Double = Math.Truncate(number)
            Return number - wholePart
        End Function

        <TestMethod()> Public Sub SplitDoubleAsDecimal1()
            Dim number As Double = 0.65 + 0.05
            Dim fractionalPart As Double = CDbl(DecimalFractionalPart(CDec(number)))
            Assert.AreEqual(0.70000000000000007, number)
            Assert.AreEqual(0.70000000000000007, fractionalPart) '<- Fails
        End Sub

        <TestMethod()> Public Sub SplitDoubleAsDecimal2()
            Dim number As Double = 0.70000000000000007
            Dim fractionalPart As Double = CDbl(DecimalFractionalPart(CDec(number)))

            Assert.AreEqual(0.70000000000000007, number)
            Assert.AreEqual(0.70000000000000007, fractionalPart) '<- Fails
        End Sub

        <TestMethod()> Public Sub SplitDoubleAsDouble1()
            Dim number As Double = 1.65

            Assert.AreEqual(1.65, number)
            Assert.AreEqual(0.65, DoubleFractionalPart(number)) '<- Fails
        End Sub

        <TestMethod()> Public Sub SplitDoubleAsDouble2()
            Dim number As Double = 1.0 + 0.65
            Assert.AreEqual(1.65, number)
            Assert.AreEqual(0.65, DoubleFractionalPart(number)) '<- Fails
        End Sub

End Class
_
公共类基本数字测试
函数DecimalFractionalPart(ByVal数作为十进制数)作为十进制数
Dim wholePart As Decimal=数学截断(数字)
返回编号-全零件
端函数
函数doubleFractionLPart(ByVal编号为Double)为Double
Dim wholePart As Double=数学截断(数字)
返回编号-全零件
端函数
公共子拆分DoubleAsDecimal1()
双精度尺寸编号=0.65+0.05
Dim SectionalPart As Double=CDbl(小数部分(CDec(数字)))
Assert.AreEqual(0.700000000000007,数字)
Assert.AreEqual(0.700000000000007,分馏部分)

REM Add: Imports System.Runtime.CompilerServices

<Extension()>
Public Function getFractionalPart(ByVal number As Single) As Single
    Return number - Math.Truncate(number)
End Function

<Extension()>
Public Function getFractionalPart(ByVal number As Double) As Double
    Return number - Math.Truncate(number)
End Function

<Extension()>
Public Function getFractionalPart(ByVal number As Decimal) As Decimal
    Return number - Math.Truncate(number)
End Function
将打印:

    4619454727784602010
    4619454727784602009
    4606281698874543309
    4606281698874543304
原因是,
10*0.69
6.9
不同,这是因为
double
是一个近似值。还请注意,
10*0.69
6.9
仅相差1个尾数增量。它们的小数部分差异大于尾数增量1的原因是IEEE 754-增量不是常数。接近0的值更准确,这不是一个bug,而是一个特性,因为这是最常见的

我不确定你想修什么

如果您想打印出
正确的
值,那么可以使用Jon Skeet的方法
ToExactString

这基本上就是其他人对小数所做的。
    4619454727784602010
    4619454727784602009
    4606281698874543309
    4606281698874543304