0

I am using a Math.Round function in my program as follows

Math.Round((ProductWeightByType * 4.18), 2)

This works perfect except for when the last character is already a 0 then it drops that 0 so example $1.70 becomes $1.7

How do i fix this?

LabRat
  • 1,996
  • 11
  • 56
  • 91
  • 3
    There is no "last character" in a number. Math.Round is not dropping any character because it doesn't operate on strings. Maybe in your case ProductWeightByType is a string? Then you are doing it wrong in the first place and should put `Option Strict On` as the first line of your code file. – djv Dec 15 '21 at 19:55
  • There aren't metadata running around with floating point numbers to say how many decimal places they're rounded to. Thus, the string conversion code will make a best guess about what's most correct, and in the general case, it will not preserve ending zeroes (because it doesn't know where those zeroes are significant and where they are not). Note that 1.7 isn't exactly representable in binary FP, so the libraries already are prettying up your number by hiding the least-significant fractional bits. – Craig Dec 16 '21 at 14:27

2 Answers2

1

When dealing with money, use Decimal. It will not suffer from precision issues as Double does. Oh, it's not clear that you're not using Decimal. Well it's also not clear that your not using strings. There are no characters in numbers, rather in strings. But here is an approach which uses proper typing

Sub Main()
    Dim ProductWeightByType As Decimal = 0.4056D
    Dim cost As Decimal = 4.18D
    Dim formattedCost As String = $"{cost:C2}"
    Dim weightedCost As Decimal = ProductWeightByType * cost
    Dim formattedWeightedCost As String = $"{weightedCost:C2}"

    Console.WriteLine($"Cost: {cost}")
    Console.WriteLine($"Formatted Cost: {formattedCost}")
    Console.WriteLine($"Weight: {ProductWeightByType}")
    Console.WriteLine($"Weighted Cost: {weightedCost}")
    Console.WriteLine($"Formatted Weighted Cost: {formattedWeightedCost}")

    Console.ReadLine()
End Sub

Cost: 4.18
Formatted Cost: $4.18
Weight: 0.4056
Weighted Cost: 1.695408
Formatted Weighted Cost: $1.70

Actually, you should probably not use Math.Round here for money. You may start to accumulate a loss or gain of fractions of pennies if you continue to round and use that value. Of course, if you want to display the cost, then format as currency just as the other answer did (mine does it as well twice).

Note, it's important to show how if the value is $1.695408 then it is rounded to $1.70, gaining $0.004592. Keep your cost in its original unspoiled numeric format without rounding, and just use C2 format for display only.

djv
  • 15,168
  • 7
  • 48
  • 72
0

you should try using string format, something like this could do what you need:

String.Format("{0:C2}", Math.Round((ProductWeightByType * 4.18), 2))
MorenajeRD
  • 849
  • 1
  • 11
  • 27
  • Okay that works what dose "{0:C2}" do? – LabRat Dec 15 '21 at 19:28
  • {0: <= this part specifies what parameter you are pointing (parameter 0 in this case). C2} <= this part specifies the format, C for currency format, 2 for two decimal places – MorenajeRD Dec 15 '21 at 19:37
  • 2
    @LabRat - For more information regarding the formatting options, I'd suggest visiting the official Microsoft documentation: https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings – David Dec 15 '21 at 19:39