1

We need to apply two rounding as the below rules:

if the 3rd number is between 0 and 4 --> +0
if the 3rd number is between 5 and 9 --> +1

I have tried the below but is not what we need

Module VBModule
    Sub Main()
        Console.WriteLine("142.5700 --> " & Math.Round(142.5700,2,MidpointRounding.ToEven))
        Console.WriteLine("142.5710 --> " & Math.Round(142.5710,2,MidpointRounding.ToEven))
        Console.WriteLine("142.5720 --> " & Math.Round(142.5720,2,MidpointRounding.ToEven))
        Console.WriteLine("142.5730 --> " & Math.Round(142.5730,2,MidpointRounding.ToEven))
        Console.WriteLine("142.5740 --> " & Math.Round(142.5740,2,MidpointRounding.ToEven))
        Console.WriteLine("142.5750 --> " & Math.Round(142.5750,2,MidpointRounding.ToEven))
        Console.WriteLine("142.5760 --> " & Math.Round(142.5760,2,MidpointRounding.ToEven))
        Console.WriteLine("142.5770 --> " & Math.Round(142.5770,2,MidpointRounding.ToEven))
        Console.WriteLine("142.5780 --> " & Math.Round(142.5780,2,MidpointRounding.ToEven))
        Console.WriteLine("142.5790 --> " & Math.Round(142.5790,2,MidpointRounding.ToEven))
    End Sub
End Module
142.5700 --> 142.57
142.5710 --> 142.57
142.5720 --> 142.57
142.5730 --> 142.57
142.5740 --> 142.57
142.5750 --> 142.57  this is wrong we need to have 142.58
142.5760 --> 142.58
142.5770 --> 142.58
142.5780 --> 142.58
142.5790 --> 142.58

i try to fix my below code ... but i still not take the correct output

''' Public Function calculateTax (gameId As String, multiplier As String, CSWinning As String) As String CSWinning = CSWinning.Replace(".",",") Dim wins As Decimal = 0 Dim firstTax As Decimal = CDec(0.15) Dim secondTax As Decimal = CDec(0.2)

    If String.IsNullOrEmpty(multiplier) OrElse multiplier.Equals("0") Then
        multiplier = "1"
    End If
    
    Dim winningsMinuscolumns As String = ((CDec(CSWinning) - getColumnCostByGame(gameId)) *CDec(multiplier.Replace("[","").Replace("]",""))).ToString
    
    'Check initially if winning sum is smaller than 100 
    If CDec(winningsMinuscolumns) <= CDec(100) Then
        wins = CDec(CSWinning)
        'Check initially if winning sum is smaller than 500 
    Else If CDec(winningsMinuscolumns) <= CDec(500)
        Dim taxedSum As Decimal = CDec(winningsMinuscolumns) - CDec(100)
        wins = CDec(CDec(CSWinning) - 100) - CDec(taxedSum * firstTax)
        wins = wins + CDec(100)
        'Check initially if winning sum is larger than 500 
    Else
        Dim taxedSum As Decimal = CDec(winningsMinuscolumns) - CDec(500)
        wins = CDec(CDec(CSWinning) - 500) - CDec(taxedSum * secondTax)
        wins = (CDec(400) - (CDec(400) * firstTax)) + wins
        wins = wins + CDec(100)
    End If
    Report.Info("BeforeRound  " & (wins))
    Report.Info("AfterRound  " & roundEven(wins))
    
    Return (roundEven(wins) * CDec(multiplier.Replace("[","").Replace("]",""))).ToString
End Function

    Public Function roundEven(num As Decimal) As Double
    Report.Info("Inside   " & num)
    Report.Info("Inside  cdbl " & CDbl(num))
    Return Math.Round(CDbl(num),2,MidpointRounding.ToEven)
    
End Function

''' 00:14.902 Info User BeforeRound 142,5750
00:14.932 Info User Inside 142,5750
00:14.961 Info User Inside cdbl 142,575
00:14.994 Info User AfterRound 142,57
'''

Luca Ruggeri
  • 121
  • 1
  • 7
  • 1
    It's because you are [using `double`s](https://stackoverflow.com/q/588004/11683). With `decimal`s, `142.5750` is rounded to `142.58`. [Add `@`](https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/type-characters) to your numeric literals. You also appear to want `AwayFromZero`, not `ToEven`. – GSerg Sep 29 '20 at 11:18

4 Answers4

2

This code is using floating point numbers which means 142.575 isn't quite 142.575 due to scaling errors. If you try to print the number with more than 13 fractional digits, eg:

Console.WriteLine("{0:N14}",142.575)

You'll get

142.57499999999999

If you use a decimal literal though, you'll get the expected result. The following line :

Console.WriteLine("{0:N24}",142.575D)

produces

142.575000000000000000000000

and

Math.Round(142.575D,2,MidpointRounding.ToEven)

produces

142.58
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
0

try to use Math.round(142.575D,2,MidpointRounting)

output will be 142.58

0

Try using .AwayFromZero instead of .ToEven. This uses Double.

    For d As Double = 142.57# To 142.58# Step 0.001#
        Console.WriteLine("{0:n4} --> {1}", d, Math.Round(d, 2, MidpointRounding.AwayFromZero))
    Next

The real question is what do the numbers represent(i.e. money or scientific calculation)? If this is monetary use Decimal. If scientific use double.

dbasnett
  • 11,334
  • 2
  • 25
  • 33
0

I just used the original strings and formatted them to 2 decimal places.

Sub Main()
    Dim lst As New List(Of String) From {"142.5700", "142.5710", "142.5720", "142.5730", "142.5740", "142.5750", "142.5760", "142.5770", "142.5780", "142.5790"}
    For Each s In lst
        Console.WriteLine($"{s}--->{CDbl(s):N2}")
    Next
    Console.ReadKey()
End Sub
Mary
  • 14,926
  • 3
  • 18
  • 27