Thank you for your comment

Numbers in Racket are similar to those you’d find in other languages, with two caveats.

First, all numbers are *complex numbers*, meaning they have a real part and imaginary part. A number can be written with one or both parts. You write the imaginary part of a complex number by appending an Xi suffix, where X is any real number. A number written without an imaginary part is treated as if it had been written with +0i.

(complex? 3) ; true

(real-part 3) ; 3

(imag-part 3) ; 0

(imag-part 3+0i) ; 0

(= 3 3+0i) ; true

(real-part 4+9i) ; 4

(imag-part 3-8i) ; -8

(* +i +i) ; -1

(real-part 3) ; 3

(imag-part 3) ; 0

(imag-part 3+0i) ; 0

(= 3 3+0i) ; true

(real-part 4+9i) ; 4

(imag-part 3-8i) ; -8

(* +i +i) ; -1

In practice, this just means that you get complex numbers “for free”: they’re already in the default numeric environment. You don’t need to import another library. If you only use real numbers, everything will still work the way you expect it to.

Second, Racket distinguishes *exact* and *inexact* numbers. An exact number is a number whose real and complex parts are both integers or rational fractions. By default, Racket will use exact numbers when it can. This means that accurate arithmetic is possible:

(+ 1/3 1/5) ; in most languages 0.533..., but 8/15 in Racket

1 | (+ 1/3 1/5) ; in most languages 0.533..., but 8/15 in Racket |

An inexact number is anything else, including all floating-point numbers. To force an exact number like 3 to behave as an inexact number, write it as 3.0. Inexact numbers are also returned by trigonometric & logarithmic functions. The result of an operation between an inexact number and another number will also be inexact:

(exact? 3) ; true

(exact? 3.0) ; false

(exact? 3+4i) ; true

(exact? 3.0+4i) ; false

(exact? (sin 1)) ; false

(exact? (+ (sin 1) 3)) ; false

(exact? (* 3.0 3.0)) ; false

(exact? 3.0) ; false

(exact? 3+4i) ; true

(exact? 3.0+4i) ; false

(exact? (sin 1)) ; false

(exact? (+ (sin 1) 3)) ; false

(exact? (* 3.0 3.0)) ; false

Exact numbers are slower, however, so if you don’t need full precision, you might as well use inexact. You can convert between the two with inexact->exact and exact->inexact. You can also coerce an operation to produce an inexact result by inserting an inexact term:

Racket has the usual welter of math operations and comparisons. Unlike other languages, many of these functions can take any number of arguments (that is, they are variadic). So a comparison like < can be used with a list of numbers to determine if the whole sequence is strictly increasing.

Numbers can be notated in hexadecimal with the #x prefix, in octal with the #o prefix, or binary with the #b prefix:

#x10 ; 16

#o20 ; 16

#b10000 ; 16

#o20 ; 16

#b10000 ; 16

1 2 3 | #x10 ; 16 #o20 ; 16 #b10000 ; 16 |

See number->string and string->number.