Penny calculator mod division - vb.net

I have an assignment for a beginners VB class, and I have looked for examples for a penny calculator and have read them and tried to figure out where I am going wrong. I have a text box that takes the number of pennies you want to figure out. If you input 101 pennies it comes back with 1 dollar and 1 penny.
Strangely it works for up to 137 pennies. That comes back with 1 dollar 1 quarter 1 dime 2 pennies. If it goes to 138 or higher it just screws up. If I input 138 I get 1 dollar, 2 quarters, 1 dime, 1 nickel, 3 pennies. If I use 17 I get 1 quarter, 2 dimes, 1 nickel, 2 pennies.
Here is the arithmetic portion of my code.
DolBack = intLeftOver / 100
intLeftOver = intLeftOver Mod 100
LblDolRes.Text = DolBack.ToString
QrtBack = intLeftOver / 25
intLeftOver = intLeftOver Mod 25
LblQrtRes.Text = QrtBack.ToString
DimBack = intLeftOver / 10
intLeftOver = intLeftOver Mod 10
LblDimRes.Text = DimBack.ToString
NicBack = intLeftOver / 5
intLeftOver = intLeftOver Mod 5
LblNicRes.Text = NicBack.ToString
PenBack = intLeftOver
LblPenRes.Text = PenBack.ToString
I have tried to look my code over and look at other examples, but apparently I'm doing it a little differently. If anyone could point out the apparent major flaw in my code or my way of doing it I would appreciate it.
Further clarifying I have looked at the post at
Penny Calculator
Obviously there are a few differences with the actual arithmetic. In the link given is that because that is the only way to do it without rounding issues?
there are 100 pennies in a dollar, 25 pennies in a quarter, 10 pennies in a dime, 5 pennies in a nickel.
EDIT: Thanks for the help and pointing out my error. It's appreciated.

You're right that it's a rounding error. Use
DolBack = intLeftOver \ 100
instead of
DolBack = intLeftOver / 100
(and the same for the other ones) and you'll see a very different result.
The reason is that the / operator will do floating point division, regardless of the values either side of it, so 38/25 will yield an answer of 1.52, which rounds upwards (as you suspected) when assigned back to the variable, which is defined as an Integer. On the other hand, the \ operator will do integer division, truncating rather than rounding.

The Math.DivRem method is helpful for this kind of problem.
Dim dollars As Integer
Dim fifty As Integer
Dim quarter As Integer
Dim dime As Integer
Dim nickel As Integer
Dim pennies As Integer = 137
dollars = Math.DivRem(pennies, 100, pennies)
fifty = Math.DivRem(pennies, 50, pennies)
quarter = Math.DivRem(pennies, 25, pennies)
dime = Math.DivRem(pennies, 10, pennies)
nickel = Math.DivRem(pennies, 5, pennies)

Related

Calculation issue in Kotlin

So i am just doing a simple calculation in my app but somehow I'm not getting expected answer with the formula.
var i = 90 / 60 * 1000
This always returns 1000 instead of 1500
It seems some issue with the floating point from 90 / 60 operation, but I'm not sure how to handle it in Kotlin.
The whole number (integer) division 90 / 60 results in 1, namely the places in front of the decimal point. Better divide by a floating point number:
var i = 90 / 60f * 1000
// result: 1500.0

Penny round up in VB.Net

Pennie round up work like this
For amount like 10.31 or 10.32 it becomes 10.30
For amount 10.33 and 10.34 it becomes 10.35
For amount 10.36 and 10.37 it becomes 10.35
For amount 10.38 and 10.39 it becomes 10.40
Please help me to achieve like this, I tried everything but no success, I will always thankful...
Here's a function that demonstrates how you can use the Mod operator to get a remainder from a number and choose what to do with it:
Public Function RoundPenny(amount As Single) As Single
Dim integerAmount As Integer = amount * 100
Dim remainder As Integer = integerAmount Mod 5
Select Case remainder
Case 0, 1, 2
integerAmount -= remainder
Case 3, 4
integerAmount += (5 - remainder)
End Select
Return integerAmount / 100
End Function

VB.net // how do you half round a number down?

So for example I need to half the number 43 to an integer, however when I do this it rounds the 21.5 made to 22 when I want it to be rounded down to 21. How do I do this? I'm using VB.net
Did you try Math.Truncate(43.0 / 2.0)? This will divide by two, and then drop any fraction, leaving only the integer part of the division.
Well rounding to 23 is correct... mathematically, however, if you want to round down:
Example: (WPF)
Dim a As Integer = 43
Dim b As Integer = CInt(Math.Floor(a / 2))
Label1.Content = b
Example: (WinForms)
Dim a As Integer = 43
Dim b As Integer = CInt(Math.Floor(a / 2))
Label1.Text= b
Another way is 43 >> 1 (this is a logical right shift - the fastest method). 43 \ 2 (this is an integer divide - second fastest).

Confused about how to go about doing this program

The question is as follows. A customer needs a specific amount of paper. The charges on the paper are:
.10 for single sheets.
.055 per sheet in multiples of 100.
.04 per sheet in multiples of 500.
.03 per sheet in multiples of 1000.
I know you have to use mod division somewhere. I'm not sure if my variables are set up correctly, and my brain is about to melt. Sad right? haha. I would greatly appreciate some help with this. Cheers :)
Option Explicit On
Imports system
Module paperp
Sub Main()
Dim papercost As Double
Dim onetpackage As Integer
Dim fivehpackages As Integer
Dim onehpackages As Integer
Dim singlesheets As Integer
Console.Writeline("Number of 1000 packages:")
onetpackage = convert.toint32(Console.Readline())
Console.Writeline("Number of 500 packages:")
fivehpackages = convert.toint32(Console.Readline())
Console.Writeline("Number of 100 packages:")
onehpackages = convert.toint32(Console.Readline())
Console.Writeline("Number of single sheets:")
singlesheets = convert.toint32(console.Readline())
Console.Out.Writeline("Number of 1000 packages:")
Console.Out.Writeline(onetpackage)
Console.Out.Writeline("Number of 500 packages:")
Console.Out.Writeline(fivehpackages)
Console.Out.Writeline("Number of 100 packages:")
Console.Out.Writeline(onehpackages)
Console.Out.Writeline("Number of single sheets:")
Console.Out.Writeline(singlesheets)
Console.Out.Writeline("Your total Cost is:")
Console.Out.Writeline(papercost)
End Sub
End Module
With that code you just have to add the price per package:
papercost = _
0.03 * 1000.0 * onetpackage + _
0.04 * 500 * fivehpackages + _
0.055 * 100 * onehpackages + _
0.1 * singlesheets
However, to make the assignment make sense, I think that you should really just input the total number of sheets, and then calculate the number of packages. You could use the modulo to calculate the remaining sheets after calculating the number of packages, but it's just as simple to use substraction:
onetpackage = Math.Floor(totalsheets / 1000)
totalsheets -= onetpackage * 1000
Why not loop through each amount (e.g. 1000, 500, 100, 1), and with the no of sheets the user specifies in a variable, the logic would be like so:
Predefined vars: no_of_sheets (the users input), working_amount = no_of_sheets, current_index = 0, count = 0, amounts (array) = (1000, 500, 100, 1), costs = (0.03, 0.04, 0.055, 0.1), total = (0, 0, 0, 0)
While (working_amount > 0)
if current_index < 4
if (working_amount - amounts[current_index]) >= 0
total[current_index]++
working_amount = working_amount - amounts[current_index]
else
current_index++
endif
endif
endwhile
Now you have an array with the amounts of each block, e.g. an array of (1, 2, 3, 4) means 1 x 1000 sheets, 2 x 500, 3 x 100, 4 x 1
Then you can just multiply each bit by their price.
HOpe that helps.
Your assignment question is an example of the Knapsack problem, but fortunately a very simple variant of it.
You don't necessarily need to use the modulo operator - you can do it iteratively. Start off with the most expensive product (which provides the best price-per-item ratio) then "buy" as many as you can with your starting money (keep subtracting from the money until you can't afford it), then move on to the next afforable product and repeat until you can't afford anything.

Rounding a number to the nearest 5 or 10 or X

Given numbers like 499, 73433, 2348 what VBA can I use to round to the nearest 5 or 10? or an arbitrary number?
By 5:
499 -> 500
2348 -> 2350
7343 -> 7345
By 10:
499 -> 500
2348 -> 2350
7343 -> 7340
etc.
It's simple math. Given a number X and a rounding factor N, the formula would be:
round(X / N)*N
Integrated Answer
X = 1234 'number to round
N = 5 'rounding factor
round(X/N)*N 'result is 1235
For floating point to integer, 1234.564 to 1235, (this is VB specific, most other languages simply truncate) do:
int(1234.564) 'result is 1235
Beware: VB uses Bankers Rounding, to the nearest even number, which can be surprising if you're not aware of it:
msgbox round(1.5) 'result to 2
msgbox round(2.5) 'yes, result to 2 too
Thank you everyone.
To round to the nearest X (without being VBA specific)
N = X * int(N / X + 0.5)
Where int(...) returns the next lowest whole number.
If your available rounding function already rounds to the nearest whole number then omit the addition of 0.5
In VB, math.round has additional arguments to specify number of decimal places and rounding method. Math.Round(10.665, 2, MidpointRounding.AwayFromZero) will return 10.67 . If the number is a decimal or single data type, math.round returns a decimal data type. If it is double, it returns double data type. That might be important if option strict is on.
The result of (10.665).ToString("n2") rounds away from zero to give "10.67". without additional arguments math.round returns 10.66, which could lead to unwanted discrepancies.
'Example: Round 499 to nearest 5. You would use the ROUND() FUNCTION.
a = inputbox("number to be rounded")
b = inputbox("Round to nearest _______ ")
strc = Round(A/B)
strd = strc*B
msgbox( a & ", Rounded to the nearest " & b & ", is" & vbnewline & strd)
For a strict Visual Basic approach, you can convert the floating-point value to an integer to round to said integer. VB is one of the rare languages that rounds on type conversion (most others simply truncate.)
Multiples of 5 or x can be done simply by dividing before and multiplying after the round.
If you want to round and keep decimal places, Math.round(n, d) would work.
Here is our solution:
Public Enum RoundingDirection
Nearest
Up
Down
End Enum
Public Shared Function GetRoundedNumber(ByVal number As Decimal, ByVal multiplier As Decimal, ByVal direction As RoundingDirection) As Decimal
Dim nearestValue As Decimal = (CInt(number / multiplier) * multiplier)
Select Case direction
Case RoundingDirection.Nearest
Return nearestValue
Case RoundingDirection.Up
If nearestValue >= number Then
Return nearestValue
Else
Return nearestValue + multiplier
End If
Case RoundingDirection.Down
If nearestValue <= number Then
Return nearestValue
Else
Return nearestValue - multiplier
End If
End Select
End Function
Usage:
dim decTotal as Decimal = GetRoundedNumber(CDec(499), CDec(0.05), RoundingDirection.Up)
Simply ROUND(x/5)*5 should do the job.
I cannot add comment so I will use this
in a vbs run that and have fun figuring out why the 2 give a result of 2
you can't trust round
msgbox round(1.5) 'result to 2
msgbox round(2.5) 'yes, result to 2 too
something like that?
'nearest
n = 5
'n = 10
'value
v = 496
'v = 499
'v = 2348
'v = 7343
'mod
m = (v \ n) * n
'diff between mod and the val
i = v-m
if i >= (n/2) then
msgbox m+n
else
msgbox m
end if
Try this function
--------------start----------------
Function Round_Up(ByVal d As Double) As Integer
Dim result As Integer
result = Math.Round(d)
If result >= d Then
Round_Up = result
Else
Round_Up = result + 1
End If
End Function
-------------end ------------
I slightly updated the function provided by the "community wiki" (the best answer), just to round to the nearest 5 (or anything you like), with this exception : the rounded number will NEVER be superior to the original number.
This is useful in cases when it is needed to say that "a company is alive for 47 years" : I want the web page to display "is alive for more than 45 years", while avoiding lying in stating "is alive for more than 50 years".
So when you feed this function with 47, it will not return 50, but will return 45 instead.
'Rounds a number to the nearest unit, never exceeding the actual value
function RoundToNearestOrBelow(num, r)
'#param num Long/Integer/Double The number to be rounded
'#param r Long The rounding value
'#return OUT Long The rounded value
'Example usage :
' Round 47 to the nearest 5 : it will return 45
' Response.Write RoundToNearestBelow(47, 5)
Dim OUT : OUT = num
Dim rounded : rounded = Round((((num)) / r), 0) * r
if (rounded =< num) then
OUT = rounded
else
OUT = rounded - r
end if
'Return
RoundToNearestOrBelow = OUT
end function 'RoundToNearestOrBelow
To mimic in Visual Basic the way the round function works in Excel, you just have to use:
WorksheetFunction.Round(number, decimals)
This way the banking or accounting rounding don't do the rounding.