Number
KupCAD has one number type, Number: a 64-bit floating-point number. 5, 5.0, 1_000,
2.5e-3 and 0x1F are all Numbers, and a whole number is simply one with no fraction
(5.0.integer? is true). Lengths are millimetres: see Units. For the operators
(+, %, **, bitwise operators and comparison), see
Operators.
Arithmetic on finite numbers never produces infinity or NaN: an operation that would raises
instead, a RangeError when the result is past the largest Number (2 ** 1024), a
ZeroDivisionError for a division or modulo by zero (1 / 0, 0 / 0), and a MathError for
a result that isn’t a number ((-8) ** 0.5).
Printing
Section titled “Printing”A Number prints in plain digits while every digit is exact, and without a decimal point when it is whole. From 1e16 (past 2^53, where floats skip whole numbers) and below 1e-6 it prints in scientific notation.
puts 2.5 # 2.5puts 7.0 # 7puts 2 ** 53 # 9007199254740992puts 2 ** 60 # 1.152921504606847e18puts 0.0000001 # 1e-7puts 0.1 + 0.2 # 0.30000000000000004A minus written against a number is part of it, as in Ruby: -2.abs is 2, and -2 ** 2 is
still -4.
Constants
Section titled “Constants”| Constant | Value |
|---|---|
Number::INFINITY |
Positive infinity. Arithmetic never produces it, so a script that needs it writes this. |
Number::NAN |
Not a number. <, <=, > and >= with it are false; == finds it equal to itself, unlike Ruby. Test for it with nan?. |
Number::EPSILON |
The gap between 1 and the next Number, 2.220446049250313e-16: a scale for tolerances. |
Every length in a model is in millimetres. These methods write a length in another unit and give it in millimetres.
n.mmn.cmn.mn.inch| Method | Gives |
|---|---|
mm |
The number itself, for a script that names its units. |
cm |
The number times 10. |
m |
The number times 1000. |
inch |
The number times 25.4. |
Returns: Number.
Raises: RangeError when the length in millimetres is past the largest Number.
puts 2.cm # 20puts 1.inch # 25.4plate = cube(x: 4.inch, y: 6.cm, z: 3.mm)Rounding and conversion
Section titled “Rounding and conversion”n.round(digits = 0)The number rounded to digits decimal places, halves away from zero. A negative digits
rounds to tens, hundreds and so on. More digits than a Number holds leave it unchanged.
| Parameter | Type | Default | Description |
|---|---|---|---|
digits |
Number | 0 |
Decimal places to keep; negative for tens, hundreds, … |
Returns: Number.
Raises: ValueError when digits isn’t finite.
puts 2.5.round # 3puts -2.5.round # -3puts 3.14159.round(2) # 3.14puts 1234.round(-2) # 1200n.ceilThe least whole number not below n. Returns: Number.
n.floorThe greatest whole number not above n. Returns: Number.
n.absThe number without its sign. Returns: Number.
n.to_iThe number truncated toward zero: 2.7.to_i is 2, -2.7.to_i is -2. Returns:
Number.
n.to_fThe number itself (there is only one number type). Returns: Number.
n.to_sThe number as puts prints it. Returns: String.
puts 2.7.ceil # 3puts 2.7.floor # 2puts -3.abs # 3puts 7.0.to_s.inspect # "7"Questions
Section titled “Questions”n.odd?n.even?Whether a whole number is odd, or even. Returns: Boolean.
Raises: ValueError for a number with a fraction, which has no parity (2.5.odd?).
n.zero?n.positive?n.negative?Whether the number is 0, greater than 0, or less than 0. Returns: Boolean.
integer?
Section titled “integer?”n.integer?Whether the number is whole and finite: 5 and 5.0 are, 5.5 and Number::INFINITY
aren’t. Returns: Boolean.
finite?
Section titled “finite?”n.finite?n.infinite?n.nan?Whether the number is finite, is positive or negative infinity, or is Number::NAN.
Returns: Boolean.
between?
Section titled “between?”n.between?(lo, hi)Whether lo <= n <= hi. Returns: Boolean.
Raises: ArgumentError when lo is greater than hi.
n.clamp(lo, hi)The number kept within lo..hi: lo when it is below, hi when it is above.
Math.clamp(n, lo, hi) is the same. Returns: Number.
Raises: ArgumentError when lo is greater than hi.
puts 4.even? # trueputs 5.0.integer? # trueputs 15.clamp(0, 10) # 10puts 5.between?(1, 10) # trueCounting
Section titled “Counting”These take whole numbers and call their block with each count in turn. A break value in the
block ends the count and becomes the method’s result; otherwise the result is the receiver.
n.times { |i| ... }Calls the block with 0, 1, … up to n - 1. A negative n calls it never.
Returns: the receiver.
Raises: ValueError when n isn’t whole; ArgumentError without a block.
n.upto(limit) { |i| ... }Calls the block with n, n + 1, … up to limit included. Returns: the receiver.
Raises: ValueError when either number isn’t whole; ArgumentError without a block.
downto
Section titled “downto”n.downto(limit) { |i| ... }Calls the block with n, n - 1, … down to limit included. Returns: the receiver.
Raises: ValueError when either number isn’t whole; ArgumentError without a block.
pegs = []4.times { |i| pegs.push(cylinder(r: 2, h: 10).translate(x: i * 10)) }1.upto(3) { |i| puts i } # 1, 2, 33.downto(1) { |i| puts i } # 3, 2, 1For counts with a step or a fraction, use a Range:
(0..1).step(0.25).each { |t| ... }.