Neobook Tip: Fract Int Sign - Decompose Number Into Its Parts

Contributed by Sam Cox:

This subroutine decomposes a numeric value into useful parts: [Sign], [Int], and [Fract] such that Math "[Sign]*([Int]+[Fract])" "" "[Value]" recreates the original value.
USAGE

SetVar "[Args]" "Value,Decimals"
Gosub "FractIntSign"

The "Decimals" parameters is optional and defaults to "9". To use the default, the usage is:

USAGE WITH DEFAULT VALUE OF DECIMALS

SetVar "[Args]" "Value"
Gosub "FractIntSign"

CODE

:FractIntSign
StrParse "[Args]" "," "[Arg]" "[Argc]"
If "[Argc]" "=" "1"
SetVar "[Arg2]" "9"
Endif
If "[Arg1]" "<" "0"
SetVar "[Sign]" "-1"
Math "Abs([Arg1])" "9" "[Arg1]"
Else
SetVar "[Sign]" "1"
Endif
Math "[Arg1]-0.499999999999999" "0" "[Int]"
Math "[Arg1]-[Int]" "[Arg2]" "[Fract]"
Return

Neobook Tip: Divmod And Isleap

Contributed by Sam Cox:

Given a positive integer numerator and positive integer denominator, the DIVMOD subroutine returns the integer quotient in variable [Div] and the integer remainder in variable [Mod]. The calling syntax is:

SetVar "[Args]" "Numerator,Denominator"
Gosub "DivMod"

Example:

SetVar "[Num]" "2001"
SetVar "[Denom]" "4"
SetVar "[Args]" "[Num],[Denom]" ... or just SetVar "[Args]" "2001,4"
Gosub "DivMod"
AlertBox "DivMod Example" "[Num] Div [Denom] = [Div]|[Num] Mod [Denom] = [Mod]"

Here is the DIVMOD subroutine:

CODE

:DIVMOD
StrParse "[Args]" "," "[Arg]" "[Argc]"
Math "[Arg1]/[Arg2]" "9" "[DivModTemp]"
Math "[DivModTemp]-0.499999999999999" "0" "[Div]"
Math "[Arg2]*[Div]" "0" "[DivModTemp]"
Math "[Arg1]-[DivModTemp]" "0" "[Mod]"
Return

Let's use the DIVMOD subroutine to write an ISLEAP subroutine (below) to determine whether a four-digit year such as 2001 is a leap year. The answer ("True" or "False") is returned in variable [isLeap]. The calling syntax is:

SetVar "[Args]" "FourDigitYear"
Gosub "isLeap"

Example:

SetVar "[SomeYear]" "1946"
SetVar "[Args]" "[SomeYear]" ... or just SetVar "[Args]" "1946"
Gosub "isLeap"
AlertBox "isLeap Example" "Is [SomeYear] a leap year? --- [isleap]"

Recall that in our modern western calendar, a four-digit year is a leap year if it is evenly divisible by 4 unless it also evenly divisible by 100 (turn of the century). But every fourth turn of the century is a leap year, so year 2000 is a leap year but years 1900 and 2100 are not.

Here is the ISLEAP subroutine.

CODE

:ISLEAP
StrParse "[Args]" "," "[Arg]" "[Argc]"
SetVar "[isLeapYYYY]" "[Arg1]"
SetVar "[Args]" "[isLeapYYYY],100"
Gosub "DivMod"
If "[Mod]" "=" "0"
SetVar "[Args]" "[isLeapYYYY],400"
Gosub "DivMod"
Else
SetVar "[Args]" "[isLeapYYYY],4"
Gosub "DivMod"
Endif
If "[Mod]" "=" "0"
SetVar "[isLeap]" "True"
Else
SetVar "[isLeap]" "False"
Endif
Return

Neobook Tip: Atan2

Contributed by Sam Cox:

Here is a NeoBook ATAN2 subroutine based on a definition found via Google.

DEFINITION FROM GOOGLE

CODE

atan2(y,x) :=
case 1: x > 0
atan(y/x)
case 2: x < 0
sign(y)*(pi - atan(abs(y/x)))
case 3: x = y = 0
0
case 4: x = 0
sign(y)*pi/2

ATAN2 SUBROUTINE USAGE

SetVar "[Args]" "Yvalue,Xvalue"
Gosub "Atan2"
CODE

:ATAN2
..ATAN2 INPUT: [Args] = "Y,X"
..ATAN2 OUTPUT: [Atan2] = angle in radians = atan(y/x) adjusted for quadrant

..uncomment the next line if you haven't defined [pi] elsewhere
..SetVar "[pi]" "3.141592654"

StrParse "[Args]" "," "[Arg]" "[Argc]"
If "[Arg1]" "<" "0"
SetVar "[SignY]" "-1"
Else
SetVar "[SignY]" "1"
Endif
If "[Arg2]" "=" "0"
If "[Arg1]" "=" "0"
..case 3
SetVar "[Atan2]" "0"
Else
..case 4
Math "[SignY]*0.50*[pi]" "9" "[Atan2]"
Endif
Else
If "[Arg2]" ">" "0"
..case 1
Math "Atan([Arg1]/[Arg2])" "9" "[Atan2]"
Else
..case 2
Math "[SignY]*([pi]-Atan(Abs([Arg1]/[Arg2])))" "9" "[Atan2]"
Endif
Endif
Return

:: Next >>