Calcutta

Platform independent versatile calculator for large numbers written in Java

Calcutta is a console based calculator with scripting capabilities. The main purpose is to serve as a programmer's calculator, e.g. to convert numbers between different number systems. Since it represents all numbers by rational fractions internally, there are no errors introduced by rounding. E.g. 3*(1/3) is not nearly 1, but exactly 1. Furthermore, Calcutta's internal number representation is only limited by the RAM available. There is no restriction due to the typical 32bit or 64bit bounds of integers or doubles.

Features

Author

Name Volker Oth
Born 1971
Country Germany
Occupation Embedded C software development (automobile)
Contact You might contact me by mail if you have questions/bug reports/suggestions regarding Calcutta: VolkerOth (at) GMX.de

Home

Official Homepage
Bitbucket Project Homepage

Details of the latest changes can be found here.

Source Code

As of version 0.86, Calcutta became an Open Source project. All source files are released under the Apache License 2.0. In a nutshell that means you can use them and modify them even for closed source or commercial projects, as long as you leave some copyright info in and give appropriate credit. See the linked Apache License for details.
Each file of the source code should contain a header with the license information.

The whole source code, the icons and the HTML help are now stored in a Git repository hosted by Bitbucket.
I recommend to use SourceTree to handle the repository but there are several other tools and also Eclipse plugins.

Repository URL: https://bitbucket.org/fade0ff/calcutta

 

Disclaimer

Calcutta is provided "as is" without warranty of any kind. Use it at your own risk.

Calcutta is freeware in the sense of "free for all to use".Download it, give it to your friends or whatever.
If you intend to put it as download on your site, please make a reference to official homepage.Same is true for distribution on magazine CDs/DVDs.
If you plan to distribute Calcutta as part of a commercial tool (which includes Shareware tools), please contact me before via Email.

As of version 0.86, Calcutta is also "free software", as all parts of the source are released under licenses approved by the Free SoftwareFoundation. See chapter Source Codefor details.

The algorithm to convert a periodic number into a rational fraction is inspired by the great German math site of  Arndt Brünner.Also some of the irrational Taylor approximation algorithms are based on his work.
Calcutta also uses a fast factorial algorithm by Peter Luschny.

Examples

Expression
Comment
prime(2**31-1)
        out = true
This number is indeed prime and we can find out in the tenth of a second
a=1;b=a++        
          out = 1

b        
          out = 1

a        
          out = 2
Note that the postincrement ++ works as it should: a is increased after b is assigned the value of a (still 1) and after the whole expression is evaluated (also out=1).
fraction(1.34p456)
        out = 22387/16650
Rational number with endless periods can be expressed as rational fraction. Indeed there is no loss of precision as long as no irrational function as sin,sqrt etc. is used.
hex(65536)
        out = 0x010000
Get hexadecimal output
bin(0x7e)
        out = 0b01111110
get binary output
(1+2*3-4/(2*3))
        out = 6.3333333333333333

fraction(out)
        out = 19/3

out*6
        out = 38
Note that the variable out is always overwritten with the last result. Also note that even if a decimal is printed out, the internal representation is always a rational fraction. That's why multiplication with 6 ends with an integer number though the operand had an endless period
fac(2000)
        out = 0.3316275092450633e+5736
factorial of 2000. This is way beyond the scope of normal calculators or even double precision. Try to print out the whole number with full(out)
hex(0x80)
        out = 0x0080

hex(-128)
        out = 0x80

~0x80;
        out = -129

hex(out)
        out = 0xff7f

Note that while 0x80 seems to fit into a byte, it is automatically evaluated as 0x0080 to express that it's unsigned, while hex(-128) is evaluated as 0x80: here the most significant bit is set, so it's a negative number.
As 0x80 is internally represented as 0x0080, the binary complement evaluated to 0xff7f, which can only be evaluated as negative number, as the most significant bit is set.
bin(0b111 ^ 0b101)
        out = 0b00000010
This goes to show that "^" is not a "to the power of" operator, but the binary XOR. Also note that binary numbers are always extended to the next byte, word, dword etc. boundary
true ^ true
        out = false
And yes, as in Java, the XOR is also defined on boolean values
full(2**150)
        out = 1427247692705959881058285969449495136382746624
Already quite a large number. But not nearly as large as it can get ;)
5<<3 == 5*8
        out = true
Was to be expected
false && ((z=1)==1)
        out = false

z

z
^
Empty or invalid expression
Note that "&&" and "||" are boolean short-circuit operators. If the left side is sufficient to evaluate the expression (false && exp is always false), the right side is not evaluated. In this case, 'z' is not set to 1. Therefore it's still undefined!
false & ((w=1)==1)
        out = false

w
        out = 1
Same example with  non-short-circuit operator &. This time the right side is evaluated and 'w' is defined.
sqrt(2**2000)
        out = 10.7150860718626732e+300
Note that functions like sqrt are not simply passed to the double sqrt. Most simple calculators will fail here.
2
        out = 2
2;
        out = <UNDEF VALUE>
A separator consumes an existing value
a = {1, "lurch", {2,true}}
        out = {1,"lurch",{2,true}}
a[1]
        out = "lurch"
a[2]
        out = {2,true}
a[2][1]
        out = true
a[2][0] = "new"
        out = {1,"lurch",{"new",true}}
Define a list by putting value separated by commas into curved braces
Access list elements by using index in brackets (reading or writing is allowed)
Lists are allowed as list elements -> multidimensional lists


Menus

Syntax

Numeric Literals

Integer numbers:
1, 2e3, 1971e+3
Decimal numbers (p marks beginning of periodic part)
1.345, 2e-3,  1.2p3
Hex numbers:
0xdeadbeef, 0xe
Binary Numbers:
0b010101
Octal Numbers:
070, 066

Note! 32e-3 is evaluated as 0.032 (32*10-3) while 0x20e-3 is evaluated as 523 (0x20e - 3)
Note! 077 is interpreted as octal (decimal 63), while 088 is interpreted as decimal 88 since it obviously can't be octal.

String Literals

There is support for string literals, e.g. "lurch". String literals can be assigned to variables, concatenated via the infix "+"or "+=" operators and printed with the "print" function.
There are more functions like sfill, replace, insert or sub which are explained later on.

Boolean Literals

The literals true and false are supported. Note thatrelational operators like "==" return boolean values.

List Literals

Lists are enclosed in curly braces and the list elements are separated by commas. Every value (number, boolean, String, List) is allowed. Note that lists can contain lists. Of course you can also use variables and expressions as list elements. Note however that these are evaluated at the moment of the list creation. After this, the list content is static (no references to the variables or expressions used to calculate the value). See later for more in depth explanation of lists.

Variables

Variables are defined by writing a value to them. The variable type is that of the last value it was assigned to. Variable names have no length limitations, consist of alphanumeric characters ([0..9], [a-z],[A..Z],"_")  and must not start with a numeric character. E.g."my_1st_var" is OK, but "1st_var" is not allowed. Variables can be used in any context in which you could use a literal.

Examples:
a=1;b=2 No need to define them, just assign a value
a=1; a="oink"; a=true 1st a is a number, then a string, then a boolean
a=c Now c is not defined yet -> this will result in an error
my_1st_string = "Hello World" Now we have a string
my_1st_boolean = true And now a boolean

Comments

As in C and Java, two types of comments are supported: Block comments start with "/*" and end with "*/". Nesting is not supported! Nested occurrences of "/*" before "*/" will be ignored. Line comments start with "//" and last until the newline character.

Operators

Nearly all operators known in C and Java are available.
Operator
Use
Precedence
Valid on
Description
+
+op1
1
Number
Marks numeric value as positive
++
++op1
op1++
1
Number
Preincrement, postincrement
-
-op1
1
Number Negative value of operand
--
--op1
op1--
1
Number
Predecrement, postdecrement,
~
~op1
1
Integer Number
Binary complement
!
!op1
1
Integer Number, Boolean
Logical complement (true - false, 0 - >0)
**
op1**op2
1
Number
op1 to the power of op2
*
op1*op2
2
Number
Multiplication
/
op1/op2
2
Number
Division
%
op1%op2
2
Integer Number
Integer Division Remainder
+
op1+op2
3
Number, String, List
Addition, String-Concatenation, List-Concatenation
-
op1-op2
3
Number
Subtraction
<<
op1<<op2
4
Integer Number
Shift left
>>
op1>>op2
4
Integer Number
Shift right
<
op1<op2
5
Number,String
Smaller than (result: boolean)
<=
op1<=op2
5
Number,String Smaller than or equal (result: boolean)
>
op1>op2
5
Number,String Larger than (result: boolean)
>=
op1>=op2
5
Number,String Larger than or equal (result: boolean)
==
op1==op2
6
Number, Boolean, String, List
Equals (result: boolean)
!=
op1!=op2
6
Number, Boolean, String, List
Not equal (result: boolean)
&
op1&op2
7
Integer Number, Boolean
Integer Number: binary AND, boolean: logical AND (no short-circuit!)
^
op1^op2
8
Integer Number, Boolean
Integer Number: binary XOR, boolean: logical XOR (no short-circuit!)
|
op1|op2
9
Integer Number, Boolean
Integer Number: binary OR, boolean: logical OR (no short-circuit!)
&&
op1&&op2
10
Integer Number, Boolean
logical AND (short-circuit!)
||
op1||op2
11
Integer Number, Boolean
Logical OR (short-circuit!)
=
var=exp
13
Left Side: variable,
Right side: any expression
Defines variable var if it doesn't exist yet and assigns it to the value of the expression on the right side
*= var*=op 14 Left: variable
Right: numeric expression
same as var = var * (op)  (multiplication)
/= var/=op 14 Left: variable
Right: numeric expression
same as var = var / op   (division)
+= var+=op 14 Left: variable
Right: Number, String, List
same as var = var + op   (addition/ Concatenation)
-= var-=op 14 Left: variable
Right: Number
same as var = var - op   (subtraction)
<<= var<<=op 14 Left: variable
Right: Number
same as var = var << op  (shift left)
>>= var>>=op 14 Left: variable
Right: Number
same as var = var >> op   (shift right)
|= var|=op 14 Left: variable
Right: Number.Boolean
same as var = var | op  (or)
&= var&=op 14 Left: variable
Right: Number, Boolean
same as var = var & op   (and)
^= var^=op 14 Left: variable
Right: Number, Boolean
same as var = var ^ op   (xor)
 

Casting Operators

All casting operators have precedence 1, they also share the common syntax "(cast)op"
Cast Operator
Valid on
Description
(u8),(u08),(byte)
Number
Casts expression to unsigned 8bit value (0..255)
(s8), (s08)
Number
Casts expression to signed 8bit value (-128..128)
(u16),(word),(char)
Number
Casts expression to unsigned 16bit value (0..65535)
(s16), (short)
Number
Casts expression to signed 16bit value (-32768..32767)
(u32),(dword)
Number
Casts expression to unsigned 32bit value (0..4294967295)
(s32),(int)
Number
Casts expression to signed 32bit value (-2147483647..2147483646)
(u64),(qword)
Number
Casts expression to unsigned 64bit value (0..18446744073709551616)
(s64), (long)
Number
Casts expression to signed 64bit value (-9223372036854775807..9223372036854775806)
(double)
Number
Castto double
(integer)
Number
Cast to integer number (same as trunc(operand))
(string) any value Converts a value to a string. The resulting string will look exactly as the default output on the console.

Built in arithmetic functions


Function
Description
abs(x)
Absolute value of number x
trunc(x)
Integer part of number x (cutting of decimal part)
floor(x)
Integer i closest to number x with i <= x
ceil(x)
Integer i closest to number x with i >= x (same as -floor(-x) )
round(x)
Integer closest to number x + 0.5 (same as floor(x+0.5) )
pow(x,N)
Calculates number x to the power of number N (same as x**N)
root(x,N)
Calculates the Nth root of number x (same as x**(1/N) )
sqrt(x)
Calculates the square root of number x (same as root(x,2) )
fac(x)
Calculates factorial of number x (normally written as x!, but "!" is logical complement)
prime(x)
Returns boolean if integer number x is (probably) a prime number
exp(x)
Returns Euler's number e raised to the power of number x
log(x)
Returns the natural logarithm (base e) of number x
log10(x)
Returns the logarithm (base 10) of number x
ld(x)
Returns the logarithm digitalis (base 2) of number x
bits(x)
Returns the number of bits needed to represent the integer number x
sin(x)
Returns the trigonometric sine of a radian angle x (number)
sinh(x)
Returns the trigonometric hyperbolic sine of a radian angle x (number)
asin(x)
Returns the trigonometric arc sine of a radian angle x (number)
cos(x)
Returns the trigonometric cosine of a radian angle x (number)
cosh(x)
Returns the trigonometric hyperbolic cosine of a radian angle x (number)
acos(x)
Returns the trigonometric arc cosine of a radian angle x (number)
tan(x)
Returns the trigonometric tangent of a radian angle (number)
tanh(x)
Returns the trigonometric hyperbolic tangent of a radian angle (number)
atan(x)
Returns the trigonometric arc tangent of a radian angle (number)

Built in misc functions


Function
Description
print(x)
println(x)
Print value x on the console (x can be a number, boolean or string)
println works as print, but adds a linefeed
hex(x)
Show integer number x in hexadecimal representation*
bin(x)
Show integer number x in binary representation*
oct(x) Show integer number x in octal representation*
full(x)
Show number x as accurate as possible
BEWARE! For rational numbers with more digits after the decimal point than the internal scale provides, the result will be less precise.
E.g. full(1/3)==(1/3) results in false, since 1/3 is precise, but full(1/3) is not!!!
fraction(x)
Show number x as a rational fraction
defined(x)
Returns true, if the variable x is defined, else false. Will not work on values!
load(x)
Load file with name x (must be a string!). Files can contain all the operators, literals and functions described here.
E.g. load("test.clc")
die(x)
Immediately exits the current expression evaluation and creates a user defined parse exception x, where x must be a string.
E.g.  a==1 || die("a is not 1");
rnd() Returns random number N where 0 <= N <= 1
time() Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
clear() Undefines all user variables and user functions
listv() Returns a sorted list with all defined variables (as strings)
listf() Returns a sorted list with all defined user functions (as strings)
eval(x) Evaluates the expression inside string <x>. E.g. eval("1+3*2") will evaluate as 7.
Every operator, function and literal is allowed within the expression, only quotes (") are forbidden.

*Note: the output functions bin/hex/oct represent negative numbers as binary complements. E.g. -1 will be represented as 0xff, 0b11111111 or0377 (octal). The base for the binary complement is the next larger integer that can be represented by a power of two bytes. E.g. for -512, two bytes are needed. Therefore the binary complement is(1<<16)-512 = 0xfe00.
To  differentiate positive from negative numbers, the output of  bin/hex will have leading zeroes for positive numbers. E.g. hex(255) will result in "0x0ff",while hex(-1) will result in "0xff".
Note that this is not possible for octal numbers as they always start with a zero by definition.

Built in list/string functions

Function
Description
lfill(value,size)

Returns a list filled with value until size is reached
    'a= fill(true,3)'  results in {true,true,true}
sfill(string,size) Returns a string filles with string until size is reached
    'a= sfill("ab",5)' results in "ababa"
sub(string,pos,len) Returns a substring of string starting at position pos and containing len characters
    'sub("12345",2,3)' results in "345"
sub(list,pos,len) Returns a sublist of list starting at position pos and containing len list elements
    'sub({1,2,3,4,5},2,3)' results in {3,4,5}
insert(string,insert,pos) Returns a string with the string insert inserted into string string at position pos     'insert("12345","AB",2)' results in "12AB345"
insert(list,insert,pos) Returns a list with the list insert inserted into list list at position pos     'insert({1,2,3,4,5},{"A","B"},3)' results in {1,2,3,"A","B",4,5}
replace(string,replace,pos) Returns a string with the string replace replaced in string string beginning with position pos     'replace("12345","AB",2)' results in "12AB5"
replace(list,replace,pos) Returns a list with the list replace replaced in list string beginning with position pos     'replace({1,2,3,4,5},{"A","B"},2)' results in {1,2,"A","B",5}
index(string1,string2) Returns (0 based) index of string2 inside string1, if found, else -1 (searching from beginning)
index(list,value) Returns (0 based) index of value inside string1, if found, else -1 (searching from beginning)
lastindex(string1,string2) Returns (0 based) index of string2 inside string1, if found, else -1 (searching from end)
lastindex(list,value) Returns (0 based) index of value inside string1, if found, else -1 (searching from end)
size(variable) returns the size of a variable.
For a list, this is the number of elements:
    'a={1,2,3,{1,2,3}}; size(a)'  results in 4
For a String, this is the number of characters
    'a="0123456789"; size(a)' results in 10
For any other value (number, boolean), this is 1

Built in constants

Two built in numbers at the moment: PI and E.

More on Lists

List literals are defined like this:
{ <elem_0> [,<elem_1>, ... <elem_n> }

To read and write to list elements, use brackets to access the index (starting with 0):
variable[index_0][ [index_1] ... [index_n] ]
Things to consider:
Examples for definitions:
{} empty list
{1,2,3}
        out =  {1,2,3}
simple list
{true, 2, "sheep" }
        out =  {true, 2, "sheep" }
mixed list
{1, {1,2,3}, 3}
        out = { 1, {1,2,3}, 3}
list inside list
a=1; b=2; { a, b, 3}
        out = {1,2,3}
Note that the variables are evaluated when creating the list
{ sin(0), cos(0), tan(0) }
        out = {0,1,0}
Same with functions

Examples for access:
a = {1,2,3}; a[0]
        out = 1
Just like in C or Java
a = {1,2,3}; a[0] = a[2] = 0; a
        out = {0,2,0}
Indexed variables behave just like ordinary variables. You can write to them and also right association is working.
b={ {1,2}, {3,4}, {4,5} }; b[0][0] = b[2][0] = 0;b
        out = {{0,2},{3,4},{0,5}}
Same with two dimensions
a = { 1, 2, 3 }; a[3]
        Index 3 out of bounds.
Neither reading nor writing to an undefined index is allowed.
{1,"a",true, {1,2}} == {1,"a",true, {1,2}}
        out = true
equality operator works on lists as well
a = {}; a = a + {1}; a = a + {2}; a
        out = {1,2}
plus operator allows list concatenation

User defined functions

The keyword function is used to define user functions. The keyword is followed by the function name,a list of typeless parameters and the function body in curly braces:
function <name> ( <param> [,<param> ...] ) { <body> }
Function  names have no length limitations, consist of alphanumeric characters ([0..9], [a-z], [A..Z],"_")  and must not start with a numeric character. E.g. "my_1st_function" is ok, but "1st_function" is not allowed.

Things to consider:

function square(a) {
    a*a
}

square(4)
        out = 16

square(true)
        Number expected on the left side of operator
The return value is just the value of the expression "a*a"



Works with numbers


Doesn't work with boolean
function square(a) {
    a*a;
}

square(4);
        out = <UNDEF VALUE>
Beware! The semicolon after the last statement of the function consumes the value
function test(a,b) {
    c=a*b;
    println(c);
    d=a+b;
    println(d);
}
Two parameters here. Use as many as you want.
lurch = 2;

function lurchtest() { println(lurch); lurch = 3; println(lurch) }

lurchtest()
2
3
        out = 3

lurch
        out = 2
Note that first the global variable is read (which contains 2).
Then a local variable is written to.
With the next read access, the local variable is read, which now
hides the global variable!!!
function ctest(a,b) { c }
This is allowed, since the syntax is correct.
However when you call this function, it will fail if no global
variable c exists.
It will work however if the variable exists!

Conditionals

The keywords if and else are used to define conditionals. Syntax:
if  ( <condition> ) { <if-statements> } [ else { <else-statements> } ]

Remarks:
a = 1;
if ( a == 1) { b = 0 } else { b = 1 }
        out = 0
b is assigned 0, note that the result of the statement equals the if branch

a = 1;
b = if (a==1) {0} else {1}
        out = 0

This does the same as the example above by directing assigning the statement to b. Note that this is perfectly allowed in contrary to C etc. where you would need to use the "?:" operator

a = 1;
if ( a == 1) { 0; } else { 1; }
        out = <UNDEF VALUE>

Note that the semicolon consumes the value. Thus the return value is undefined!!!
a = 1;
sin ( if (a==1) {PI} else {1})
        out = 0
Note how the result of the statement can be passed as parameter
if (false) {1}
        out = <UNDEF VALUE>
There is no else branch and no statement after this that would define a result. Thus the value of this statement is undefined!


Furthermore the ternary operator "?" is defined as in C and Java.

(<condition>) ? <true_statement> : <false_statement>

Remarks:

a = 1;
( a == 1 ) ? ( b = 0 ) : ( b = 1 )
        out = 0

b is assigned 0, note that the result of the statement equals the true branch

a = 1;
b = (a==1) ? 0 : 1
        out = 0

This does the same as the example above by directing assigning the statement to b. Note that this is perfectly allowed in contrary to C etc. where you would need to use the "?:" operator

a = 1;
(a == 1) ? 0; : 1;
        Evaluator Stack underflow

Note that the semicolon consumes the value. Thus the return value is undefined!!!

a = 1;
(a == 0) ? 0; : 1;
        out = <UNDEF VALUE>
a
        out = 1

Note that the semicolon after the false statement consumes the return value of the whole expression. Still a is defined correctly. Using parentheses around "1" would create an evaluator stack underflow as well.
a = 1;
sin ( (a==1) ? PI : 1)
        out = 0
Note how the result of the statement can be passed as parameter


FOR Loop

The keyword for is used to define a for loop. Syntax:
for  ( <init_statement> ; <loop_condition>; <iterator_statement> ) { <loop_body> }

Remarks:
for (i=0; i<10;i++) { print(i) }
0123456789
Nothing spectacular. Just note that since "i++" evaluates 9, while "i" is already 10!
for (i=0; i<10;i=i+1) { print(i) }
0123456789
        out = 10
"i=i+1"  works exactly the same as "++i" would
for (i=sin(0); i<3**2+1;i=i+1) { print(i) }
0123456789
You can use expressions and functions inside the statements of course
for (;;) { print("#") }
        Invalid condition
The loop condition shall not be omitted!


FOREACH Loop

The keyword foreach is used to define a for each loop. Syntax:
foreach  ( <loop_variable> ; <list>) { <loop_body> }

Remarks:
a={1,2,3}; foreach(i;a) { print(i) }
123
Simple example
foreach(i;{1,2,3}) { print(i) }
123
Same with a list literal
foreach(i;{1,2,3}) { print(i); foreach(j;{"a","b","c"}){print(j)} }
1abc2abc3abc
Nested foreach loops
a={1,2,3}; foreach(i;a){ a={"a","b"}; print(i) }
123
a
        out = {"a","b"}
Note that changing the variable 'a' works, but doesn't influence the loop behavior.

DO WHILE Loop

The keyword do is used to define a do while loop. Syntax:
do { <loop_body> } while  ( <loop_condition> )

Remarks:

i=0;do { print(i) }while(++i<10)
0123456789
No init statement, so you have to put it in a separate statement.


WHILE Loop

The keyword while is used to define a while loop.Syntax:
while  ( <loop_condition> ) { <loop_body> }

Remarks:
i=0;while (i<10) { print(i++) }
0123456789
No init statement, so you have to put it in a separate statement.

More examples:

Simple recursive factorial

Though there is a built in function for factorials, let's just write our own simple algorithm just to show that recursion works. Save the example to a file called "factorial.clc".
function factorial(n) {
    if (n<=1) {
        1
    } else {
        n*factorial_recursive(n-1)
    }
}
load("factorial.clc")
factorial(200)
        out = 0.7886578673647905e+375
fac(200)
        out = 0.7886578673647905e+375

Galton's Board:

This simulates Galton's Board, in which balls are dropped through a triangular array of nails. There are N rows, where the 1st row has one nail, the 2nd row has two nails and so on. A ball is dropped above the first nail. At each nail, it falls either to the left or to the right (50% probability). At the bottom, there are (rows+1) slots in which the balls can land. The distribution of the balls within the slots  is a binomial distribution. Save the text to a file "galton.clc", then load it with 'load("galton.clc")'. Run it e.g. with "galton(4,1000)" (4rows, 5 slots, 1000 trials).
function galton(rows, trials) {       
    // init
    slot = lfill(0,rows+1);
       
    // run trials
    for (trial = 0; trial < trials; trial++) {
        position = 0;
        for (pos = 0; pos < rows; pos++) {
            if (rnd() >= 0.5) {
                position++;   
            }                
        }
        slot[position]++;
    }
       
    // output
    for (pos = 0; pos <= rows; pos++) {
          println("Slot " + (string)(pos+1) +
              " contains " + (string)slot[pos] + " balls.");

    }
}
load("galton.clc")
galton(4,1000)

Slot 1 contains 49 balls. Slot 2 contains 240 balls.
Slot 3 contains 374 balls.
Slot 4 contains 273 balls.
Slot 5 contains 64 balls.

99 Bottles of Beer

Of course Calcutta is also able to handle one of the most important problems in today's computer science (well, kind of), namely printing out the whole text of "99 bottles of beer". See www.99-bottles-of-beer.net for implementations in thousands of strange languages. Save the text to a file "99bottles.clc", then load it with 'load("99bottles.clc")'.
// Calcutta version of 99 Bottles of beer    
b1  = " bottle of beer";
bn  = " bottles of beer";
otw = " on the wall";

for (i=100; i>0; i--) {
    b = if (i>1) {bn} else {b1};
    println ((string)i+b+otw+", "+(string)i+b+".");
    println("Take one down and pass it around,");
    b = if (i-1>1) {bn} else {b1};
    println((string)(i-1)+b+otw+".");
    println("");
}
load("99bottles.clc")

100 bottles of beer on the wall, 100 bottles of beer.
Take one down and pass it around,
99 bottles of beer on the wall.
...
...
...
1 bottle of beer on the wall, 1 bottle of beer.
Take one down and pass it around,
0 bottle of beer on the wall.