【问题标题】:Truncating Double with VBA in excel在excel中使用VBA截断双精度
【发布时间】:2012-07-05 15:33:04
【问题描述】:

我需要截断双精度值的小数位数,以便在文本框中显示。如何使用 vba 实现这一目标?

【问题讨论】:

    标签: excel double decimal-point vba


    【解决方案1】:

    如果你想四舍五入这个值,那么你可以使用 Round 函数(但要注意 VBA 的 Round 函数使用 Banker 的四舍五入,也称为 round-to-even,它会四舍五入a 5 向上或向下;要使用传统四舍五入,请使用格式)。

    如果您想截断值而不进行四舍五入,则无需像接受的答案那样使用字符串 - 只需使用数学:

    Dim lDecimalPlaces As Long: lDecimalPlaces = 2
    Dim dblValue As Double: dblValue = 2.345
    
    Dim lScale = 10 ^ lDecimalPlaces
    Dim dblTruncated As Double: dblTruncated = Fix(dblValue * lScale) / lScale
    

    这产生“2.34”。

    【讨论】:

    • 我忘记了银行家的四舍五入。 +1 尽管居高临下的“只使用数学”刺拳。对于只是按照 OP 要求显示数字,如果你不太关心舍入,Format() 是工作的工具,并且比 Fix()(或 Int(),相当于 Fix()对于正数)。但是,在某些情况下,Banker 的四舍五入会引起用户的疑问,需要进行更复杂的转换。
    【解决方案2】:

    您可以使用 Int() 函数。 Debug.print Int(1.99543)

    或更好:

    Public Function Trunc(ByVal value As Double, ByVal num As Integer) As Double
      Trunc = Int(value * (10 ^ num)) / (10 ^ num)
    End Function
    

    所以你可以使用Trunc(1.99543, 4) ==> result: 1.9954

    【讨论】:

      【解决方案3】:

      这是我的尝试:

      Function TruncateNumber(decimalNum As Double, decPlaces As Integer) As Double
      'decimalNum: the input number to be truncated
      'decPlaces: how many decimal places to round to. Use 0 for no decimal places.
          decimalLocation = InStr(decimalNum, ".")
          TruncateNumber = Left(decimalNum, decimalLocation + decPlaces)
      End Function
      

      它使用字符串来避免因不同舍入方法导致的任何数学错误。它将作为 double 类型输出,因此您仍然可以对其进行自己的数学运算。

      如果将一个没有小数位的数字传递给上述函数,这将导致错误。如果这是一个问题,您可以使用以下代码:

      Function TruncateNumber(decimalNum As Double, decPlaces As Integer) As Double
      'decimalNum: the input number to be truncated
      'decPlaces: how many decimal places to round to. Use 0 for no decimal places.
          If InStr(decimalNum, ".") = 0 Then 'if there was no decimal:
              'then return the number that was given
              TruncateNumber = decimalNum
          Else 'if there is a decimal:
              'then return the truncated value as a type double
              decimalLocation = InStr(decimalNum, ".")
              TruncateNumber = Left(decimalNum, decimalLocation + decPlaces)
          End If
      End Function
      

      希望这些功能对某些人有用。我没有进行广泛的测试,但它们对我有用。

      【讨论】:

        【解决方案4】:

        您可以在 VBA 中将ROUND 用于FORMAT

        例如显示 2 位小数

        Dval = 1.56789
        
        Debug.Print Round(dVal,2)
        
        Debug.Print Format(dVal,"0.00")
        

        注意:以上将给你1.57。因此,如果您正在寻找1.56,那么您可以将 Dval 存储在一个字符串中,然后执行此操作

        Dim strVal As String
        
        dVal = 1.56789
        strVal = dVal
        
        If InStr(1, strVal, ".") Then
            Debug.Print Split(strVal, ".")(0) & "." & Left(Split(strVal, ".")(1), 2)
        Else
            Debug.Print dVal
        End If
        

        【讨论】:

        • 永远不要将数字作为文本处理。
        【解决方案5】:

        已编辑

        较新版本的 Excel (VBA) 有一个 TRUNC 函数,它已经可以正常工作了。

        对于旧版本的 EXCEL

        我想将双精度数截断为整数。

        value = Int(83.768)
        value == 83
        

        太棒了,成功了。

        根据您的 Excel (VB) 版本,这可能不适用于负数。

        value = Int(-83.768)
        value == -84
        

        VB 使用银行家四舍五入。

        Public Function Trunc1(ByVal value As Double) As Integer
          ' Truncate by calling Int on the Absolute value then multiply by the sign of the value.
          ' Int cannot truncate doubles that are negative
          Trunc1 = Sgn(value) * Int(Abs(value))
        End Function
        

        如果您想要特定的小数位,请执行 Makah 所做的仅在值周围使用 Abs 的操作,以便 Int 可以正确截断。

        Public Function Trunc2(ByVal value As Double, Optional ByVal num As Integer = 1) As Double
            ' Truncate by calling Int on the Absolute value then multiply by the sign of the value.
            ' Int cannot truncate doubles that are negative
            Trunc2 = Sgn(value) * (Int(Abs(value) * (10 ^ num)) / (10 ^ num))
        End Function
        

        【讨论】:

        • 有一个签名功能,可以一步实现sign = Abs(value) / valueSgn(value)
        【解决方案6】:

        这是我做的一个小实验......(第一次发帖和回答,如果我不遵守约定,请告诉我。

        Sub Truncate()
            
        Dim dblNum  As Double
        Dim intDecimal  As Integer
        
        dblNum = 1578.56789
        intDecimal = 2  '0 returns 1578
                        '2 returns 1578.56
                        '-2 returns 1500
        
        Debug.Print (Int(dblNum * 10 ^ intDecimal) / 10 ^ intDecimal)
        
        End Sub
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-02
          • 1970-01-01
          • 2017-12-18
          • 1970-01-01
          相关资源
          最近更新 更多