Work out premium in a textbox from database value - vb.net

Market value.
I need to work out premium the calculation is as follows:
5% on first $100 000 then $10 for each R10 000 or part of R10 000 thereafter.
So not sure how to do this.
My idea:
get value from my dataset.
Dim Value1 as bool
Dim Value2 as bool
Dim premium as bool
Dim price As String = Convert.ToString(dsVehicleFill.Tables[0].Rows[0]["VEH_MarketPrice"]) <-- Does not work.
Calculation:
Value1 = price/0.05
value2 = Value1 - price
I cant see how to do this. Im new to codeing so im stuck here.

The question about working out premium is more a math problem than a programming problem, but there are several things going on here:
Dim Value1 as bool
Dim Value2 as bool
Dim premium as bool
The bool data type is meant to represent Boolean values, i.e. their value is expected to be either 1 or 0. It makes no sense to use them here: You'll want your variables to be of type Double instead, which is suitable for fractional calculations involving currency.
As for the problem of pulling a value from your DataTable, you'll need to be more specific about what isn't working.
Now, as for the Premium formula, let's break it down (you switch between $ and R (which I assume to mean South African Rand), I'm going to just use dollars in this example):
The first $100000 earns a 5% premium
The remaining amount earns a premium of $10 for every $10000, including the final portion if it's < $10000
So you can approach the calculation with an algorithm like this:
Compare the value to $100000
If the value is <= $100000
The premium = value * 0.05
If the value is > $100000
Calculate the remainder after subtracting 100000
Divide the remainder by 10000 to find the number of $10 premiums to apply (N.B.: In many other languages, expressing x / 10000 will result in integer division, dropping any fractional component. You can force Double division by writing your constant like so: x / 10000.0. Fortunately, VB.NET defaults to Double division, as Plutonix points out in the comments.)
Take the Ceiling of this number (i.e. round it up to the nearest integer)
The premium = $5000 (5% of the first $100000) + Ceiling * $10
Implementing this in Visual Basic is left as an exercise to the reader. :)

Related

How would i separate an answer in Kotlin do print 2 different types

Hi this is my first ever program I'm tryin to write in android studio/Kotlin and I'm not sure how to proceed.
so in my program i have a few math tasks to do and it does it fine but what I need to do now is separate part of the answer then covert it then print out both parts
for example if my answer was 1.5232 i would like to convert the decimal part of the answer to a string that matches a range if its in it. the ranges I have are in the .0000 area so I would like to limit the decimal range too.
so final result would look like this
1 (whatever my string in range is)
I hope I included enough info thank you in advance.
The first part of the task is to split the number into the integer and fractional components:
val input = 1.5232
val integer = input.toInt() // rounds DOWN to nearest smaller Int
val fractional = input % 1.0 // The remainder when dividing by 1.0 is the fraction
The strategy I would use to round to the nearest fractional value given a certain precision is to multiply by that precision, and round to the nearest integer. That would give you the numerator, and the precision would be the denominator:
val denominator = 8 // fractional precision
val numerator = (fractional * denominator).roundToInt() // rounds up or down to nearest Int
Then to put it together, you can use a string template:
val result = "$integer $numerator/$denominator"
println(result)
Simplifying the fraction would be another task if you need that. You can find various algorithms for finding greatest common divisor of two numbers. Use one of those and divide the numerator and denominator by that value.

vb.net Math.Round drops last 0 in price?

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?
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.
you should try using string format, something like this could do what you need:
String.Format("{0:C2}", Math.Round((ProductWeightByType * 4.18), 2))

How do I produce a number with absolute precision of some power of 10?

Vb.net has a decimal data type.
Unlike normal double or floating points, decimal data type can store values like 0.1
Now say I have a variable like precision.
Say precision is 8
So basically I want to do
Protected Overridable Sub setPairsPricesStep2(decimalPrecission As Long, Optional base As String = "", Optional quote As String = "")
If decimalPrecission = 8 Then
Return
End If
Dim price = 10D ^ (-decimalPrecission)
setPairsPriceStep1(price, base, quote)
End Sub
There is a problem there
the result of Dim price = 10D ^ (-decimalPrecission) is double, not decimal. I can convert it to decimal but then I will lost the precission.
So what is the right way to do it? Should I just use for next but that's hardly elegant.
It's simple
I want a function that given precisions give decimal value.
For example, if precision is 1 I got 0.1. If precision is 5, I got 0.00001
I ended up doing this
For i = 1 To decimalPrecission
price *= 0.1D
Next
But surely there is a better way
Update:
Per comment, I tried
Dim e = 10D ^ -5
Dim e1 = 10D ^ -5L
The type of e and e1 are both double.
I suppose I can do Cdec(e). But then it means I have lost accuracy because normal double cannot store .1 correctly.
I want a function that given precisions give decimal value.
For example, if precision is 1 I got 0.1. If precision is 5, I got 0.00001
Since you are working with the Decimal type, the simplest way to get this result is to use the Decimal constructor that allows you to specify the scale factor.
Public Sub New (lo As Integer, mid As Integer, hi As Integer, isNegative As Boolean, scale As Byte)
From the Remarks section of the above referenced documentation,
The binary representation of a Decimal number consists of a 1-bit sign, a 96-bit integer number, and a scaling factor used to divide the integer number and specify what portion of it is a decimal fraction. The scaling factor is implicitly the number 10 raised to an exponent ranging from 0 to 28.
So you can see that if take the value of one divided by 10 to the first power, the result is 0.1. Likewise, one divided by 10 to the fifth power, the result is 0.00001.
The lo, mid, and hi arguments in the constructor could be obtained by uisng the [Decimal.GetBits Method](Decimal.GetBits Method), but for this simple case, I chose to hard code the values for the value of one stored as a decimal.
To obtain a value of 0.1D:
New Decimal(1, 0, 0, False, 1)
To obtain a value of 0.00001D:
New Decimal(1, 0, 0, False, 5)
Dim stringrepresentation = "1E-" + decimalPrecission.ToString
Dim price = Decimal.Parse(stringrepresentation, System.Globalization.NumberStyles.AllowExponent)
This is what I basically did. Basically I created a string 1E-5, for example, and use decimal.parse to get the decimal
I wonder if there is a better way but I have no idea.
Actually Jimy ways may work too but rounded to a number

VBA: difference between Variant/Double and Double

I am using Excel 2013. In the following code fragment, VBA calculates 40 for damage:
Dim attack As Variant, defense As Variant, damage As Long
attack = 152 * 0.784637
defense = 133 * 0.784637
damage = Int(0.5 * attack / defense * 70)
If the data types are changed to Double, VBA calculates 39 for damage:
Dim attack As Double, defense As Double, damage As Long
attack = 152 * 0.784637
defense = 133 * 0.784637
damage = Int(0.5 * attack / defense * 70)
In the debugger, the Variant/Double and Double values appear the same. However, the Variant/Double seems to have more precision.
Can anyone explain this behavior?
tldr; If you need more precision than a Double, don't use a Double.
The answer lies in the timing of when the result is coerced into a Double from a Variant. A Double is an IEEE 754 floating-point number, and per the IEEE specification reversibility is guaranteed to 15 significant digits. Your value flirts with that limit:
0.5 * (152 * .784637) / (133 * .784637) * 70 = 39.99999999999997 (16 sig. digits)
VBA will round anything beyond 15 significant digits when it is coerced into a double:
Debug.Print CDbl("39.99999999999997") '<--Prints 40
In fact, you can watch this behavior in the VBE. Type or copy the following code:
Dim x As Double
x = 39.99999999999997
The VBE "auto-corrects" the literal value by casting it to a Double, which gives you:
Dim x As Double
x = 40#
OK, so by now you're probably asking what that has to do with the difference between the 2 expressions. VBA evaluates mathematical expressions using the "highest order" variable type that it can.
In your second Sub where you have all of the variable declared as Double on the right hand side, the operation is evaluated with the high order of Double, then the result is implicitly cast to a Variant before being passed as the parameter for Int().
In your first Sub where you have Variant declarations, the implicit cast to Variant isn't performed before passing to Int - the highest order in the mathematical expression is Variant, so no implicit cast is performed before passing the result to Int() - the Variant still contains the raw IEEE 754 float.
Per the documentation of Int:
Both Int and Fix remove the fractional part of number and return the
resulting integer value.
No rounding is performed. The top code calls Int(39.99999999999997). The bottom code calls Int(40). The "answer" depends on what level of floating point error you want to round at. If 15 works, then 40 is the "correct" answer. If you want to floor anything up to 16 or more significant digits, then 39 is the "correct" answer. The solution is to use Round and specify the level of precision you're looking for explicitly. For example, if you care about the full 15 digits:
Int(Round((0.5 * attack / defense * 70), 15))
Keep in mind that the highest precision you use anywhere in the inputs is 6 digits, so that would be a logical rounding cut-off:
Int(Round((0.5 * attack / defense * 70), 6))
If you get rid of the Int() function on both lines where damage is calculated both end up being the same. You shouldn't be using Int as this is producing the errant behavour, you should be using CLng as you are converting to a Long variable or if damage were an Int you should use CInt.
Int and CInt behave differently. Int always rounds down to the next lower whole number - whereas CInt will round up or down using Banker's Rounding. You'll typically see this behaviour for numbers that have a mantissa of 0.5.
As for the variant and double differences, if you do a TypeName to a MsgBox for the 1st code block you'll find that both attack and defense after having been assigned values have been converted to a double despite having been declared as variant.

How do you multiply two fixed point numbers?

I am currently trying to figure out how to multiply two numbers in fixed point representation.
Say my number representation is as follows:
[SIGN][2^0].[2^-1][2^-2]..[2^-14]
In my case, the number 10.01000000000000 = -0.25.
How would I for example do 0.25x0.25 or -0.25x0.25 etc?
Hope you can help!
You should use 2's complement representation instead of a seperate sign bit. It's much easier to do maths on that, no special handling is required. The range is also improved because there's no wasted bit pattern for negative 0. To multiply, just do as normal fixed-point multiplication. The normal Q2.14 format will store value x/214 for the bit pattern of x, therefore if we have A and B then
So you just need to multiply A and B directly then divide the product by 214 to get the result back into the form x/214 like this
AxB = ((int32_t)A*B) >> 14;
A rounding step is needed to get the nearest value. You can find the way to do it in Q number format#Math operations. The simplest way to round to nearest is just add back the bit that was last shifted out (i.e. the first fractional bit) like this
AxB = (int32_t)A*B;
AxB = (AxB >> 14) + ((AxB >> 13) & 1);
You might also want to read these
Fixed-point arithmetic.
Emulated Fixed Point Division/Multiplication
Fixed point math in c#?
With 2 bits you can represent the integer range of [-2, 1]. So using Q2.14 format, -0.25 would be stored as 11.11000000000000. Using 1 sign bit you can only represent -1, 0, 1, and it makes calculations more complex because you need to split the sign bit then combine it back at the end.
Multiply into a larger sized variable, and then right shift by the number of bits of fixed point precision.
Here's a simple example in C:
int a = 0.25 * (1 << 16);
int b = -0.25 * (1 << 16);
int c = (a * b) >> 16;
printf("%.2f * %.2f = %.2f\n", a / 65536.0, b / 65536.0 , c / 65536.0);
You basically multiply everything by a constant to bring the fractional parts up into the integer range, then multiply the two factors, then (optionally) divide by one of the constants to return the product to the standard range for use in future calculations. It's like multiplying prices expressed in fractional dollars by 100 and then working in cents (i.e. $1.95 * 100 cents/dollar = 195 cents).
Be careful not to overflow the range of the variable you are multiplying into. Your constant might need to be smaller to avoid overflow, like using 1 << 8 instead of 1 << 16 in the example above.