locked
Number ranges on Math functions - Small Basic RRS feed

  • Question

  • Hi everyone on MSDN forums!

    First, I'm really pleased to find such an amazing IDE, Small Basic is, with a lot of difference, the easiest way to understand programming for everybody because of the inteface and language syntax. (Yes I'm a newbie ;-) )

    Well, I'm programming a calculator. Here is the code:

    begin:
    TextWindow.ForegroundColor = "Yellow"
    TextWindow.Write("How many numbers: ")
    answer = TextWindow.Read()
     
    If Text.StartsWith(answer, "1") Then
      TextWindow.Write("Enter first number: ")
      number1 = TextWindow.Read()
      If number1 <= 1 Then
         TextWindow.Write("Choose operator: ")
         op1["sn"] = Math.Sin(number1)
         op1["cs"] = Math.Cos(number1)
         op1["tg"] = Math.Tan(number1)
         op1["rd"] = Math.GetDegrees(number1)
         op1["dr"] = Math.GetRadians(number1)
         op1["as"] = Math.ArcSin(number1)
         op1["ac"] = Math.ArcCos(number1)
         op1["at"] = Math.ArcTan(number1)
         index = TextWindow.Read()
         TextWindow.WriteLine(op1[index])
      Else 
         TextWindow.Write("Choose operator: ")
         op2["sn"] = Math.Sin(number1)
         op2["cs"] = Math.Cos(number1)
         op2["tg"] = Math.Tan(number1)
         op2["rd"] = Math.GetDegrees(number1)
         op2["dr"] = Math.GetRadians(number1)
         op2["at"] = Math.ArcTan(number1)
         index = TextWindow.Read()
         TextWindow.WriteLine(op2[index])
         EndIf
    ElseIf Text.StartsWith(answer, "2") Then
       TextWindow.Write("Enter first number: ")
      number1 = TextWindow.Read()
      TextWindow.Write("Enter second number: ")
      number2 = TextWindow.Read()
      TextWindow.Write("Which operator want to use? ")
      op3["+"] = number1 + number2
      op3["-"] = number1 - number2
      op3["*"] = number1 * number2
      op3["/"] = number1 / number2
      op3["p"] = Math.Power(number1, number2)
      op3["r"] = Math.Power(number1, 1 / number2)
      op3["l"] = Math.Log(number1) / Math.Log(number2)
      index = TextWindow.Read()
      TextWindow.WriteLine(op3[index])
    ElseIf Text.StartsWith(answer,"help") Then
      TextWindow.WriteLine("")
      TextWindow.WriteLine("AVAILABLE COMMANDS")
      TextWindow.WriteLine("")
      TextWindow.WriteLine("--With 1 number--")
      TextWindow.WriteLine("")
      TextWindow.WriteLine("sn - Sine by radians")
      TextWindow.WriteLine("cs - Cosine by rad")
      TextWindow.WriteLine("tg - Tangent by rad")
      TextWindow.WriteLine("rd - rad to degrees")
      TextWindow.WriteLine("dr - deg to radians")
      TextWindow.WriteLine("as - Arcsine")
      TextWindow.WriteLine("ac - Arccosine")
      TextWindow.WriteLine("at - Arctangent")
      TextWindow.WriteLine("")
      TextWindow.WriteLine("--With 2 numbers--")
      TextWindow.WriteLine("")
      TextWindow.WriteLine("+ - Addition")
      TextWindow.WriteLine("- - Subtract")
      TextWindow.WriteLine("* - Multiply")
      TextWindow.WriteLine("/ - Divide")
      TextWindow.WriteLine("p - Power (No.1=Base, No.2=exponent)")
      TextWindow.WriteLine("r - Root (No.1=Radicand, No.2=Root)")
      TextWindow.WriteLine("l - Logarithm (No.2=Base)")
      TextWindow.WriteLine("")
    ElseIf Text.StartsWith(answer, "exit") Then
      Program.End()
    EndIf
    Goto begin

    The calculator runs like this:

    - First you choose the number of "numbers" you need to operate

    - Second, you choose the number(s)

    - Third, you choose the operator

    When I choose "2 numbers" and I place by numbers, for example, 35 and 35, the "famous messagebox":

    "Decimal's value is too big or small"
    en System.Decimal..ctor(Double value)   
    en Microsoft.SmallBasic.Library.Math.Power(Primitive baseNumber, Primitive exponent)   
    en _SmallBasicProgram._Main()

    ... and the program crashes.

    (Well, I have spanish version, I don't know if that is shown in the same case):

    So I noticed I need the range of numbers that Small Basic manages (globally or in every function, class, variable, ...). If you notice, in "1 number block", I split in order not to get an error because of "Math.ArcSin", "Math.ArcCos" and "Math.ArcTan", because they need a number between 0 and 1 (I'll be working on negative numbers, you can write suggestions if you want) and the program would crash if I place a number higher than 1.

    I want to do the same for "2 numbers block", if you place a number higher than "xxxxxxxxxxx", run an "Else"/"ElseIf" in order not to get the error and the program's crash.

    It would be very nice for me if you help me on this, I remember have found it but I can't remember where I have read that.

    Sorry if you notice my bad English, and I'm not used to programming vocabulary too, I'm Spanish :-)

    Wednesday, August 14, 2013 9:56 PM

Answers

  • You have very good English! I have been taking Spanish for 4 years but my programming vocabulary is poor so I will write in English.

    Unfortunately, it is difficult to predict whether a number raised to an exponent will result in an overflow (SB apparently uses the Decimal .Net type internally, whose maximum value is 79,228,162,514,264,337,593,543,950,335, but that value is to big for SB--- it must get lost somewhere in the process of casting the primitive to a decimal) 

    EDIT: I would suggest that you decide on a safe max value and use a function like this (of course, 1024 is a very small max but I used it because 2 ^ 10 = 1024)

    EDIT 2: The labels keep getting cut out of the code below, so you can use the import ID PBZ436 in Small Basic to import the program.

    MaximumValue = 1024
    Base = 2
    Exponent = 11
    
    counter = Base
    For i = 1 To (Exponent - 1) 
      TextWindow.WriteLine("Maxval/Counter=" + (MaximumValue / counter))
      If((MaximumValue / counter) < base) Then 
        Goto OVERFLOW
      Else 
        counter = counter * Base
        TextWindow.WriteLine("Counter is " + counter)
      EndIf
    EndFor
    Goto NOOVERFLOW
    
    TextWindow.WriteLine("Overflow!")
    TextWindow.ReadKey()
    Program.End()
    
    NOTextWindow.WriteLine("No overflow")
    TextWindow.ReadKey()
    Program.End()




    Please mark any answers and "vote as helpful" any posts that help you!







    Wednesday, August 14, 2013 10:51 PM
    Answerer
  • In the line:

     If Math.Power(number1, number2) > Math.Power(2, 95) Then

    you try to calculate the power function whith values which can be to big for the function. You have to check the values number1 and number2 for maximum values, and not try to use them.

    Edit:  Another possibilty is to calculate the answer only for the given operator, you can then expext that numbers are in the right range for the formula.


    Jan [ WhTurner ] The Netherlands



    Thursday, August 15, 2013 11:24 AM
    Answerer
  • ChoProg, this is a good question for all Small Basic programmer.

    Following numbers are available limits which I investigated:

    79228162514264337593543950334 + 1

    0.0000000000000000000000000001 / 10

    Math.Remainder(9007199254740992, 2)

    Math.SquareRoot(19807040628566084398385987584)

    Math.Power(31622776, 2)

    Math.Power(2, 49)

    cf. details in http://social.msdn.microsoft.com/Forums/en-US/6f2538ef-636b-468e-886f-cb7bd58a50cd/smallest-largest-numbers-that-sb-can-handle

    P.S. I'd like to write this issue as TechNet Wiki article.


    Nonki Takahashi


    Friday, August 23, 2013 7:15 AM

All replies

  • You have very good English! I have been taking Spanish for 4 years but my programming vocabulary is poor so I will write in English.

    Unfortunately, it is difficult to predict whether a number raised to an exponent will result in an overflow (SB apparently uses the Decimal .Net type internally, whose maximum value is 79,228,162,514,264,337,593,543,950,335, but that value is to big for SB--- it must get lost somewhere in the process of casting the primitive to a decimal) 

    EDIT: I would suggest that you decide on a safe max value and use a function like this (of course, 1024 is a very small max but I used it because 2 ^ 10 = 1024)

    EDIT 2: The labels keep getting cut out of the code below, so you can use the import ID PBZ436 in Small Basic to import the program.

    MaximumValue = 1024
    Base = 2
    Exponent = 11
    
    counter = Base
    For i = 1 To (Exponent - 1) 
      TextWindow.WriteLine("Maxval/Counter=" + (MaximumValue / counter))
      If((MaximumValue / counter) < base) Then 
        Goto OVERFLOW
      Else 
        counter = counter * Base
        TextWindow.WriteLine("Counter is " + counter)
      EndIf
    EndFor
    Goto NOOVERFLOW
    
    TextWindow.WriteLine("Overflow!")
    TextWindow.ReadKey()
    Program.End()
    
    NOTextWindow.WriteLine("No overflow")
    TextWindow.ReadKey()
    Program.End()




    Please mark any answers and "vote as helpful" any posts that help you!







    Wednesday, August 14, 2013 10:51 PM
    Answerer
  • Well, I have read your advice and placed a max value on 2^95 for "Math.Power", "Math.Log"... splitting available functions by "power's answer":

    ElseIf Text.StartsWith(answer, "2") Then
      TextWindow.Write("Enter first number: ")
      number1 = TextWindow.Read()
      TextWindow.Write("Enter second number: ")
      number2 = TextWindow.Read()
      TextWindow.Write("Choose operator: ")
      If Math.Power(number1, number2) > Math.Power(2, 95) Then
        op3["+"] = number1 + number2
        op3["-"] = number1 - number2
        op3["*"] = number1 * number2
        op3["/"] = number1 / number2
        index = TextWindow.Read()
        TextWindow.WriteLine(op3[index])
      ElseIf Math.Power(number1, number2) <= Math.Power(2, 95) Then
        op4["+"] = number1 + number2
        op4["-"] = number1 - number2
        op4["*"] = number1 * number2
        op4["/"] = number1 / number2
        op4["p"] = Math.Power(number1, number2)
        op4["r"] = Math.Power(number1, 1 / number2)
        op4["l"] = Math.Log(number1) / Math.Log(number2)
        index = TextWindow.Read()
        TextWindow.WriteLine(op4[index])

    But it still crashes with the same error. Am I doing anything wrong?

    Thanks for your answer gungan37, and thanks to those people who want to answer me too.

    Thursday, August 15, 2013 10:59 AM
  • In the line:

     If Math.Power(number1, number2) > Math.Power(2, 95) Then

    you try to calculate the power function whith values which can be to big for the function. You have to check the values number1 and number2 for maximum values, and not try to use them.

    Edit:  Another possibilty is to calculate the answer only for the given operator, you can then expext that numbers are in the right range for the formula.


    Jan [ WhTurner ] The Netherlands



    Thursday, August 15, 2013 11:24 AM
    Answerer
  • OK, I understand. Thanks WhTurner for your answer

    Thursday, August 15, 2013 12:00 PM
  • ChoProg, this is a good question for all Small Basic programmer.

    Following numbers are available limits which I investigated:

    79228162514264337593543950334 + 1

    0.0000000000000000000000000001 / 10

    Math.Remainder(9007199254740992, 2)

    Math.SquareRoot(19807040628566084398385987584)

    Math.Power(31622776, 2)

    Math.Power(2, 49)

    cf. details in http://social.msdn.microsoft.com/Forums/en-US/6f2538ef-636b-468e-886f-cb7bd58a50cd/smallest-largest-numbers-that-sb-can-handle

    P.S. I'd like to write this issue as TechNet Wiki article.


    Nonki Takahashi


    Friday, August 23, 2013 7:15 AM
  • ChoProg, this is a good question for all Small Basic programmer.

    Following numbers are available limits which I investigated:

    79228162514264337593543950334 + 1

    0.0000000000000000000000000001 / 10

    Math.Remainder(9007199254740992, 2)

    Math.SquareRoot(19807040628566084398385987584)

    Math.Power(31622776, 2)

    Math.Power(2, 49)

    cf. details in http://social.msdn.microsoft.com/Forums/en-US/6f2538ef-636b-468e-886f-cb7bd58a50cd/smallest-largest-numbers-that-sb-can-handle

    P.S. I'd like to write this issue as TechNet Wiki article.


    Nonki Takahashi


    Great idea! Did you ever turn this into a Wiki article? You could always just paste in the basics and add more later.

    Thanks!


    Ed Price, SQL Server Customer Program Manager (Blog, Small Basic, Wiki Ninjas, Wiki)

    Answer an interesting question? Create a wiki article about it!

    Saturday, August 31, 2013 6:56 PM
  • Ed, I wrote this as a TechNet Wiki article.

    Nonki Takahashi

    Tuesday, September 17, 2013 9:25 AM