Visual Basic Friend Error - vb.net

Im having trouble working out making a converter for mutliple currencys using multiple subs. I keep receiving an error saying that number is a friend , and therefore cannot be used in the jap conversion . can anyone help ? thank you in advance
Option Explicit On
'Option Strict On
Imports System
Module Yahtzed
Sub CANtoUSD()
Dim Number , USDConversion as Decimal
Number = Console.Readline
USDConversion =( Number * 1.0141)
Console.Writeline(USDConversion)
End Sub
Sub CANtoJAP()
Dim Number, JAPConversion as Decimal
Number = Console.Readline
JAPConversion =( Number * 79.9392)
Console.Writeline(JAPConversion)
End Sub
Sub Main()
Console.Writeline("Enter the CAN amount: ")
CANtoUSD()
CANtoJAP()
End Sub
End Module

Not a direct answer, but this requires more space than would work in a comment.
You have a fundamental design error in your code. You really want to structure it more like this:
Function CANtoUSD(Number As Decimal) As Decimal
Dim USDConversion as Decimal = 1.0141
Return USDConversion * Number
End Function
Function CANtoJAP(Number As Decimal) As Decimal
Dim JAPConversion as Decimal = 79.9392
Return JAPConversion * Number
End Function
Sub Main()
Console.Writeline("Enter the CAN amount: ")
Dim input As Decimal = Console.ReadLine()
Console.WriteLine(CANtoUSD(input))
Console.WriteLine(CANtoJAP(input))
End Sub
You don't want to mix responsibilities for you methods. The input/output should be strictly separated from the code that manipulates the data. If nothing else, this makes it easier to test that your specific conversion methods work exactly like they are supposed to, and could not be the source of your bug.
Later on, you'll learn how to also ahave a single method that accepts a key value for both source and destination types, and does a table lookup to convert any currency to any other by knowing the conversion factor to a common currency.

Related

Widening: Change in representation

Requesting your help to understand the concept of widening better!
I came across the following statement w.r.t 'Widening Conversion' in VB.Net. From the msdn documentation on the topic I found the following: Widening conversions preserve the source value but can change its representation. This occurs if you convert from an integral type to Decimal, or from Char to String. The link to the page is found below:
https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/widening-and-narrowing-conversions
My Question is as follows: I wrote the following code to understand the meaning of the statement "...preserve the source value but can change its representation". But I see no difference in the output when I print the integer or the decimal. Then what does the phrase mean....what is the meaning of "...can change its representation"?
Module Module1
Sub Main()
Dim i As Integer = 5
Dim d As Decimal = i 'widening
Console.WriteLine(i)
Console.WriteLine(d)
'Both prints "5"...no difference in representation
Console.ReadLine()
End Sub
End Module
Can someone also please give an example to demonstrate how the representation changes when we convert a char value to a string?
It means the internal presentation of the number (in your case). Try to convert, say, Single to Double:
Sub Main(args As String())
Dim sng As Single = 1.23E+32
Dim dbl As Double = sng
Console.WriteLine($"Single: {sng}")
Console.WriteLine($"Double: {dbl}")
End Sub
' Output:
' Single: 1,23E+32
' Double: 1,2300000079302825E+32

Visual Basic - newbie question - unable to assign user input to a class property

I am trying to take the user input and assign it to a property defined in a class. When I run the program, it asks for user input as expected, but displays a different result. Can someone point out where my mistake is ?
I was trying to base my simple program on this tutorial
https://learn.microsoft.com/en-us/dotnet/core/tutorials/vb-with-visual-studio
but trying to extend it to classes.
I am using the latest version of Visual Studio and Visual Basic. It's a visual basic Console App
Module Module1
Sub Main()
Dim ClassInstance As New Class1()
Console.WriteLine("Input Property 1: ")
ClassInstance.Property1 = Console.Read()
Console.Write(ClassInstance.Property1)
Console.ReadKey(True)
End Sub
Public Class Class1
Public Property1 As Integer
Public Property2 As Integer
End Class
End Module
Expected output:
"Input Property 1:" |
User input 50 |
Output 50
Console.Read reads the next character from the input, and gives you that character's code. If, for instance, you typed 5 at the prompt1, Console.Read would return 53. Why? Because that's the ASCII/Unicode code for that character (in Unicode terms, it's U+0035, which is the same number represented in hexadecimal).
If you want to read multiple characters and interpret them as an integer, you should a) be using something other than Console.Read to take the input and b) use Int32.TryParse to try to turn it into a number (because users don't always give us the input we expect).
Something like:
Module Module1
Sub Main()
Dim ClassInstance As New Class1()
Console.WriteLine("Input Property 1: ")
Dim inp = Console.ReadLine()
Dim value as Int32
If Int32.TryParse(inp, value) Then
ClassInstance.Property1 = value
Console.Write(ClassInstance.Property1)
Console.ReadKey(True)
End If
End Sub
Public Class Class1
Public Property1 As Integer
Public Property2 As Integer
End Class
End Module
(With apologies if I've made syntax errors - my VB's quite rusty)
In reality, you'd probably want to write some form of loop that prompts for user input and doesn't terminate until it successfully parses. I think Do/While would fit there - but if you're going to prompt the user more than once, you probably would want to extract the "Loop until valid input received" code into a function that takes the prompt as a parameter.
More reading - ASCII/Unicode. For characters in the "7-bit ASCII" range, basic latin characters without accents, it doesn't make much difference which references you check
1And it doesn't matter if you carried on and typed any more characters, your program only asks for/gets one of them

Visual Basic global rounding up function for other mathematical features

I'm working within Visual Basic console application.
I have created a number of mathematical features such as quadratic equation and prime factorisation.
However, my next task is to create a mathematical feature that you're able to enter and select the number of decimal places you wish to get your answers for the other mathematical features.
For example let's call this function decimalPoint:
You enter decimal point - you're asked how many decimal places you'd like your answers to. You chose 2.
You go back to the main menu and select quadratic equation, after inputting the coefficients then the output of the quadratic equation has to output in 2.d.p.
I'm able to ask the user for an input and just convert that into whatever d.p I need, but I don't know how to link it to other subs/functions.
So Far I have something along the lines:
Sub decimalPoint
dim Input As Integer
Console.WriteLine("Welcome")
Console.WriteLine("Enter amount of decimal place you wish to save to 1-5", 1-6) 'max 5dp.
input = Console.ReadLine()
End Sub
''Now I could do something like Console.WriteLine(Round(Convert.ToDecimal(input), 2)), but that's only based on whatever they input and not related to other functions/subs that I need it for. Any idea how I can link this to other subs?
notes:
It's a program with a menu.
Update: I got something along these lines now, but it's still not working.
Module Module1
Public Property MyResult As ...
Public Property MyDecimalInput As ...
Sub QuadraticFunction()
....Calculations
Console.WriteLine("Chose a decimal input: 1-5")
If ... = ... Then
Call decimalPoint()
MyResult = (....)
End Sub
Sub decimalPoint()
If MyDecimalInput = ...
Math.Round(MyResult) ...
...
End Sub
End Module
I don't know if this is what you're looking for but this is how I interpreted your question, but does this answer your question? If not let me know and I'll do my best to help :)
'converts text in textbox to integer
Dim decimalPoint As Integer = Convert.ToInt64(addTB.Text)
'stores newly rounded function into a number of user specified decimal places
Dim answer As Double = Math.Round(13.17435, decimalPoint)
'displays rounded answer
MsgBox(answer)

Need a method for storing obscenely long numbers in number format (not scientific)

How would I go about storing a very large number in number format and not scientific.
Please bear in mind that the number I will be storing is too big for the Long data type.
I've set it as a String.
I have a userform with a command button and a textbox.
Below is the sample code:
Private Sub Cmd_Click()
Dim bits As Integer
Dim out As String
bits = 64
out = 2 ^ (bits - 1)
Txt_Output.Value = out
End Sub
The above will return: 9.22337203685478E+18.
But I want 9223372036854775807.
Can anyone explain how to avoid this?
Thanks in advance.
P.S. I'm hoping to avoid having to use an array.
You can achieve that specific calculation using Decimal data types and a modification to the calculation routine:
Private Sub Cmd_Click()
Dim bits As Integer
Dim out As Variant
Dim i As Long
bits = 64
out = CDec(1)
For i = 1 to bits - 1
out = out * 2
Next
Txt_Output.Value = out
End Sub
By forcing out to be a Variant/Decimal, the calculation does not lose precision as it is being calculated. However some things, such as CDec(2) ^ CDec(63) would still lose precision as the calculation would be done using an intermediate Double precision, so you will need to be very careful as to what calculations you do.
This might give you clues as to how to generalise that method to achieve what you need.
If you have 64-bit Excel, you can use the LongLong data type.

Left value of an integer

I have a value in variable, say it is dim a as integer = 145.98
I tried to take the Left(a,2)
but it returned an error instead of returning 14
I also tried left(a.Tostring,2)
but error is the same.
Please help me solve it.
Thanks
Furqan
First off, you say that you’re using an integer but the number is actually a floating-point number, not an integer.
Secondly, the action “take the left of a number” isn’t a meaningful operation. Left is a substring operation, it’s only defined on strings.
You can turn the number into a string and then extract a substring of the decimal representation. This should work. What’s the error?
Finally, some general advice:
Put Option Strict On at the very top of ever vb file, or better yet, make this option the default in your settings. Otherwise, you’ve got a veritable hullaballoo waiting to happen because VB is very … “lenient” when it comes to questionable or downright incorrect code. This option fixes this and will flag a lot more errors. For example, the compiler would (rightfully) have complained about your assignment,
Dim a As Integer = 145.98
because as I said, you’re trying to assign a floating-point number to an integer.
First of all, 145.98 is not an integer. 145 is an integer. You might want to try Double. Second, you can only take the left of a string. You were on the right track when you added ToString, but you forgot the ()s at the end.
Dim a as Integer = 145
Dim b as Double = 145.98
Then you can do this:
Left(a.ToString(), 2)
Left(b.ToString(), 2)
Try Left(a.ToString(), 2) instead.
If your "integer" is a string, try this:
Dim a As String = "145.98"
Dim b As Int32 = 0
Int32.TryParse(a.Substring(0, 2), b)
As Konrad has said with option strict this would not compile. If you don't have it on it will perform a conversion and store only the integer part. At this point you can call tostring and then performe any operation on it as a string you would like.
With option strict
Option Strict On
Module Module1
Sub Main()
Dim I As Integer = CType(142.3, Integer)
Dim s As String = I.ToString
Console.WriteLine(Left(s, 2))
End Sub
End Module
With out optiion strict
Module Module1
Sub Main()
Dim I As Integer = 142.3
Dim s As String = I
Console.WriteLine(Left(s, 2))
End Sub
End Module
As you can see from the two example option strict will attempt to perform many conversions for you but does so at the risk of unexpected results.