Math Functions

Hello!

I’ve made simple math functions to emulate math methods from other languages into CS. Keep in mind, these functions are- simply put- primitive. There is no use of *script here, only pure CS, hence you might encounter performance issues.

Installation Guide

In your startup file, you will need a couple of variables.

startup.txt

*create n 0
*create pi "3."
*create/set implicit_control_flow true

Now you can rename n or pi, just remind yourself to also rename the variables in the math.txt file.

Speaking of math.txt. Create a math.txt file in the folder with your IF with these contents:

*comment ------------ Constants ------------

*comment ------------ pi ------------
*comment Return the number of pi. Precision included (up to 10 places)
*comment NOTE: You can increase the precision by increasing the length of the array and adding the following digit.
*comment Keep in mind that the digits SHOULD be in string format, else this function will fail.
*comment And yes, math is still possible in CS combining both int and str.
*comment gosub_scene math pi [precision]

*label pi
*temp i 0
*params x
*temp_array list 10  "1" "4" "1" "5" "9" "2" "6" "5" "3" "5"

*set pi "3."

*if x = 0
	*set n 3
	${n}

	*return

*label pi_loop

*if (i = x) and (i != 0)
	${pi}

	*return

*else 
	*set i + 1
	*set pi & {list[i]}

	*goto pi_loop

*comment ------------ Basic Functions ------------

*comment ------------ pow ------------
*comment Returns the number x raised to the power y
*comment gosub_scene math ex [x] [y]

*comment NOTE: USE WHOLE NUMBERS ONLY

*label pow
*temp i 1
*params x y
*temp z 0

*set z x

*label pow_loop

*if i = y
	*set n x
	${n}

	*return

*elseif y = 0
	*set n 1
	${n}

	*return

*elseif y = 1
	${x}

	*return

*else
	*set x * z
	*set i + 1

	*goto pow_loop

*comment ------------ sqrt ------------
*comment Returns the sqrt of a number 
*comment gosub_scene math sqrt [x] 

*comment NOTE: PRIMATIVE! 
*comment Will only work for perfect squares.
*comment Might take longer for larger numbers.
*comment Will rework this in the future.

*label sqrt
*params x
*temp i 0

*label sqrt_loop

*if (i * i) <= x
	*if (i * i) = x
		*set n i
		${n}
		*return

	*else 
		*set i + 1
		*goto sqrt_loop

*else
	Irrational number returned.

	*return

*comment ------------ fact ------------
*comment Returns the factorial of a number
*comment Iterates and descends through the number, until 1, and returns the product
*comment gosub_scene math fact [x] 

*label fact
*params x
*temp i 0
*temp z 0

*set z x

*if x = 0
	1

	*return

*else
	*label fact_loop

	*if x > 1
		*set z * (x - 1)
		*set x - 1

		*goto fact_loop

	*else
		*set n z
		${n}
		
		*return

*comment ------------ ceil ------------
*comment Rounds UP to the nearest integer
*comment gosub_scene math ceil [x] 

*label ceil
*params x

*set n 0

*label ceil_loop
*if x <= 0
	${n}

	*return

*if x > 0
	*set n + 1
	*set x - 1

	*goto ceil_loop

*comment ------------ floor ------------
*comment Rounds DOWN to the nearest integer
*comment gosub_scene math floor [x]

*label floor
*params x

*set n 0

*label floor_loop
*if x <= 0
	${n - 1}

	*return

*if x > 0
	*set n + 1
	*set x - 1

	*goto floor_loop

Make sure that the file is in the same folder your IF is in. There’s no need to put the file in your scene_list.

I’m not sure why would this be useful. I suppose it would be great for IF largely focused on gameplay elements.

So, without further a-do. Let me introduce all the current functions available.

Pi

Return the constant pi. You can return a certain precision of pi, currently up to 10 decimal digits, but you can add more digits. And yes, you can perform math equations with strings in CS.

*label pi
*temp i 0
*params x
*temp_array list 10  "1" "4" "1" "5" "9" "2" "6" "5" "3" "5"

*set pi "3."

*if x = 0
	*set n 3
	${n}

	*return

*label pi_loop

*if (i = x) and (i != 0)
	${pi}

	*return

*else 
	*set i + 1
	*set pi & {list[i]}

	*goto pi_loop

To add another digit, increase the length of the array then add the digit.

Example code:

*subscene math pi 4

Will return with:

3.1415
Exponents

Returns a value of x to the power of y.

*label pow
*temp i 1
*params x y
*temp z 0

*set z x

*label pow_loop

*if i = y
	*set n x
	${n}

	*return

*elseif y = 0
	*set n 1
	${n}

	*return

*elseif y = 1
	${x}

	*return

*else
	*set x * z
	*set i + 1

	*goto pow_loop

Keep in mind that this won’t work for rational numbers (i.e: 1.1, 2.3, 4.5).

Example code:

*subscene math pow 3 2

Will return with:

9
Square Root

Returns the value of the square root of x.

*label sqrt
*params x
*temp i 0

*label sqrt_loop

*if (i * i) <= x
	*if (i * i) = x
		*set n i
		${n}
		*return

	*else 
		*set i + 1
		*goto sqrt_loop

*else
	Irrational number returned.

	*return

Note that this function is a brute force method. It only works for perfect squares (products of numbers multiplied by itself. i.e: 4, 9, 16), otherwise will return “Irrational number returned” meaning it simply cannot calculate the expression. For example, √2. It could be possible for me to revise this to return an irrational value, but I simply don’t want to, as of now.

Example code:

*subscene math sqrt 16

Will return with:

4
Factorials

Returns the product of all whole numbers of x down to 1. Will be gradually slower as you approach larger numbers.

*label fact
*params x
*temp i 0
*temp z 0

*set z x

*if x = 0
	1

	*return

*else
	*label fact_loop

	*if x > 1
		*set z * (x - 1)
		*set x - 1

		*goto fact_loop

	*else
		*set n z
		${n}
		
		*return
Example code:

*subscene math fact 5

Will return with:

120
Ceil

Rounds UP to the nearest integer. Only possible for non-negative integers, as of now.

*label ceil
*params x

*set n 0

*label ceil_loop
*if x <= 0
	${n}

	*return

*if x > 0
	*set n + 1
	*set x - 1

	*goto ceil_loop
Example code:

*subscene math fact 4.3

Will return with:

5
Floor

Rounds DOWN to the nearest integer. Only possible for non-negative integers, as of now.

*label floor
*params x

*set n 0

*label floor_loop
*if x <= 0
	${n - 1}

	*return

*if x > 0
	*set n + 1
	*set x - 1

	*goto floor_loop
Example code:

*subscene math fact 4.3

Will return with:

4

As an example, here is a Demo for all the math functions.

This project isn’t tested well enough. If you run into problems, please provide your encounters.

If you also have any feedback/suggestions, also put them here.

5 Likes

Nice work. Could I make a suggestion that you consider submitting the parts of these that cover missing functionality to CSLIB’s math module? IMO it’s great to centralise stuff like this to share community efforts and improve visibility and reliability.

CSLIB comes with a full testing harness/framework, so would help you out there in turn. I do think providing testing for utility functions you want people to use and rely on is important.

2 Likes

Nice!

Four bits of feedback:

  1. CS has an exponential operator (^) built-in.

  2. None of the code requires implicit control flow enabled, so it’s unnecessary to include it in the list of variables the user needs to create.

  3. Keep in mind that the digits SHOULD be in string format, else this function will fail.

    The function won’t actually fail if you use numbers without quotes. You can replace *temp_array list 10 "1" "4" "1" "5" "9" "2" "6" "5" "3" "5" with *temp_array list 10 1 4 1 5 9 2 6 5 3 5 and it works fine. "1" and 1 are almost always interchangeable in CS.

  4. For returning constants, I think it’d be easier to store the digits in a string instead of an array. It’d make it easier to add digits; just replace the string instead of typing multiple array entries. But it works either way.
    E.g.,

*label return_pi
*params decimal_places
*temp pi "3.14159265358979323846"
*temp pi_return "3"
*if decimal_places > 0
    *temp i 2
    *label add_digits_loop
    *if (i <= (decimal_places + 2)) and (i <= length(pi))
        *set pi_return pi_return&(pi#i)
        *set i + 1
        *goto add_digits_loop
${pi_return}
*return


You know how the ChoiceScript wiki says:

A variable’s data type is determined simply by the type of data assigned to it when first created: if you give it a number (even just zero) it becomes a numeric data type; if you give it “something in quotes” it becomes a string data type; and if you give it either true or false (without any quotes) it becomes a boolean data type.

even though the boolean data type essentially uses an actual word as its value, it is not treated the same as the ordinary text of a string variable. It should therefore never be enclosed within “quotation marks”.

Yeah, none of that’s true.

Everything’s a string. There are no data types. The wiki is a lie.

Big Wat energy:

${"2.1"^"3"} = 9.261000000000001

${(round("-4.5"))} = -4

@{"false" Multireplace is true.|Multireplace is false.} = Multireplace is false.

${("foo42bar"#5) + 2} = 4

2 Likes

Agreed. I can try to fork the repo and make a contribution, though I’d need to make some changes to fit the modules before I commit. Unless you want the file as is?

I never knew that :sweat_smile:. I suppose I am used to math.pow() as my go to exponent, never the actual operator sign. I also searched the wiki and- not that wide- on the forums for anything related to exponents which led me thinking that exponents were never implemented.

That’s right! I second guess myself putting in CS if-else statements. I get quite annoyed debugging these statements, hence I put them as a fail-safe, for the peace of mind.

And to be honest, it’s just great thing to have on.

Yours I think is better. It’s easier for users to modify one less thing, and it’s more concise. Performance-wise, I don’t really know.


As for the whole dataypes. I was unsettled when I looked back to my own code, years ago, to find every variable was a string. Then contemplating everything when the code actually works.

Though, let’s not burst everyone’s bubble. It’s great practice to assign variables to their correct dtypes. Having ChoiceScript as my first language to have knowledgable skills in, it helped me a lot learning other languages.

1 Like

If you’re willing to make the changes, I think it would be a good exercise. It will also give you a framework for adding those missing tests. Feel free to DM me if you’re having any trouble with it.