Package squidpony.squidmath
Class NumberTools
java.lang.Object
squidpony.squidmath.NumberTools
public final class NumberTools extends Object
Various numeric functions that are important to performance but need alternate implementations on GWT to obtain it.
Super-sourced on GWT, but most things here are direct calls to JDK methods when on desktop or Android.
Some of this code makes use of "creative" bit manipulation of floats and doubles, which can sometimes allow uncommon
input-to-output patterns (as in
bounce(float)
), or even can yield a performance boost (compare
zigzag(float)
to using modulus to accomplish the same results). The bit manipulation has good performance on
GWT thanks to JS typed arrays, which are well-supported now across all recent browsers and have fallbacks in GWT in
the unlikely event of a browser not supporting them.-
Constructor Summary
Constructors Constructor Description NumberTools()
-
Method Summary
Modifier and Type Method Description static double
acos(double n)
Arc cosine approximation with very low error, based on a simplified version ofatan2(double, double)
.static float
acos(float n)
Arc cosine approximation with very low error, based on a simplified version ofatan2(float, float)
.static double
acos_(double n)
Inverse cosine function (arccos) but with output measured in turns instead of radians.static float
acos_(float n)
Inverse cosine function (arccos) but with output measured in turns instead of radians.static double
asin(double n)
Arc sine approximation with very low error, based on a simplified version ofatan2(float, float)
.static float
asin(float n)
Arc sine approximation with very low error, based on a simplified version ofatan2(double, double)
.static double
asin_(double n)
Inverse sine function (arcsine) but with output measured in turns instead of radians.static float
asin_(float n)
Inverse sine function (arcsine) but with output measured in turns instead of radians.static double
atan2(double y, double x)
Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 approximation.static float
atan2(float y, float x)
Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 approximation.static double
atan2_(double y, double x)
Altered-range approximation of the frequently-used trigonometric method atan2, taking y and x positions as doubles and returning an angle measured in turns from 0.0 to 1.0 (inclusive), with one cycle over the range equivalent to 360 degrees or 2PI radians.static float
atan2_(float y, float x)
Altered-range approximation of the frequently-used trigonometric method atan2, taking y and x positions as floats and returning an angle measured in turns from 0.0f to 1.0f, with one cycle over the range equivalent to 360 degrees or 2PI radians.static double
atan2Degrees(double y, double x)
Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 approximation, and giving a result in degrees from -180 to 180.static float
atan2Degrees(float y, float x)
Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 approximation, and giving a result in degrees from -180 to 180.static double
atan2Degrees360(double y, double x)
Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 approximation, and giving a result in degrees from 0 to 360.static float
atan2Degrees360(float y, float x)
Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 approximation, and giving a result in degrees from 0 to 360.static double
bounce(double value)
Very limited-use; takes any double and produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and down through the range.static float
bounce(float value)
Very limited-use; takes any double and produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and down through the range.static double
bounce(int valueLow, int valueHigh)
Very limited-use; takes the significand bits of a double, represented as a pair of intsvalueLow
andvalueHigh
, using all bits in valueLow and the least-significant 20 bits of valueHigh, and produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and down through the range.static double
bounce(long value)
Very limited-use; takes the significand bits of a double, represented as a long of which this uses 52 bits, and produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and down through the range.static double
cos(double radians)
A fairly-close approximation ofMath.cos(double)
that can be significantly faster (between 8x and 80x faster cos() calls in benchmarking; if you have access to libGDX you should consider its sometimes-more-precise and sometimes-faster MathUtils.cos() method.static float
cos(float radians)
A fairly-close approximation ofMath.cos(double)
that can be significantly faster (between 8x and 80x faster cos() calls in benchmarking, and both takes and returns floats; if you have access to libGDX you should consider its more-precise and sometimes-faster MathUtils.cos() method.static double
cos_(double turns)
A variation onMath.cos(double)
that takes its input as a fraction of a turn instead of in radians; one turn is equal to 360 degrees or two*PI radians.static float
cos_(float turns)
A variation onMath.cos(double)
that takes its input as a fraction of a turn instead of in radians (it also takes and returns a float); one turn is equal to 360 degrees or two*PI radians.static float
cosDegrees(float degrees)
A fairly-close approximation ofMath.cos(double)
that can be significantly faster (between 8x and 80x faster cos() calls in benchmarking, and both takes and returns floats; if you have access to libGDX, you should consider its more-precise and sometimes-faster MathUtils.cosDeg() method.static int
doubleToHighIntBits(double value)
Convertsvalue
to a long and gets the upper 32 bits of that long, as an int.static long
doubleToLongBits(double value)
Identical toDouble.doubleToLongBits(double)
on desktop; optimized on GWT.static int
doubleToLowIntBits(double value)
Convertsvalue
to a long and gets the lower 32 bits of that long, as an int.static int
doubleToMixedIntBits(double value)
Convertsvalue
to a long and gets the XOR of its upper and lower 32-bit sections.static long
doubleToRawLongBits(double value)
Identical toDouble.doubleToLongBits(double)
on desktop (note, notDouble.doubleToRawLongBits(double)
); optimized on GWT.static int
floatToIntBits(float value)
Identical toFloat.floatToIntBits(float)
on desktop; optimized on GWT.static int
floatToRawIntBits(float value)
Identical toFloat.floatToIntBits(float)
on desktop (note, notFloat.floatToRawIntBits(float)
); optimized on GWT.static int
floatToReversedIntBits(float value)
Gets the bit representation of the given floatvalue
, but with reversed byte order.static double
formCurvedDouble(long start)
A different kind of determine-like method that expects to be given a random long and produces a random double with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f.static double
formCurvedDoubleTight(long start)
A different kind of determine-like method that expects to be given a random long and produces a random double with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach 0.0 and 1.0.static float
formCurvedFloat(int start)
A different kind of determine-like method that expects to be given a random int and produces a random float with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f.static float
formCurvedFloat(int start1, int start2)
A different kind of determine-like method that expects to be given random ints and produces a random float with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f.static float
formCurvedFloat(long start)
A different kind of determine-like method that expects to be given a random long and produces a random float with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f.static double
formDouble(long seed)
Given a long as a seed, this uses its least-significant 52 bits to produce a double between 0 (inclusive) and 1 (exclusive).static float
formFloat(int seed)
Given an int as a seed, this uses its least-significant 23 bits to produce a float between 0f (inclusive) and 1f (exclusive).static double
formSignedDouble(long seed)
Given a long as a seed, this uses its least-significant 52 bits to produce a double between -1 (inclusive) and 1 (exclusive).static float
formSignedFloat(int seed)
Given an int as a seed, this uses its least-significant 23 bits to produce a float between -1f (inclusive) and 1f (exclusive).static byte
getSelectedByte(double value, int whichByte)
Gets an 8-bit section of the given doublevalue
, usingwhichByte
to select whether this should return byte 0 (least significant), 1, 2, and so on up to 7 (most significant).static byte
getSelectedByte(float value, int whichByte)
Gets an 8-bit section of the given floatvalue
, usingwhichByte
to select whether this should return byte 0 (least significant), 1, 2, or 3 (most significant).static float
intBitsToFloat(int bits)
Identical toFloat.intBitsToFloat(int)
on desktop; optimized on GWT.static double
longBitsToDouble(long bits)
Identical toDouble.longBitsToDouble(long)
on desktop; optimized on GWT.static int
lowestOneBit(int num)
Returns an int value with at most a single one-bit, in the position of the lowest-order ("rightmost") one-bit in the specified int value.static long
lowestOneBit(long num)
Returns an long value with at most a single one-bit, in the position of the lowest-order ("rightmost") one-bit in the specified long value.static double
randomDouble(long seed)
Generates a pseudo-random double between 0.0 (inclusive) and 1.0 (exclusive) using the given long seed, passing it once through the (decent-quality and very fast)ThrustAltRNG
algorithm.static float
randomFloat(long seed)
Generates a pseudo-random float between 0f (inclusive) and 1f (exclusive) using the given long seed, passing it once through the (decent-quality and very fast)ThrustAltRNG
algorithm.static float
randomFloatCurved(long seed)
Generates a pseudo-random double between -1.0 (exclusive) and 1.0 (exclusive) with a distribution that has a strong central bias (around 0.0).static double
randomSignedDouble(long seed)
Generates a pseudo-random double between -1.0 (inclusive) and 1.0 (exclusive) using the given long seed, passing it once through the (decent-quality and very fast)ThrustAltRNG
algorithm.static float
randomSignedFloat(long seed)
Generates a pseudo-random float between -1f (inclusive) and 1f (exclusive) using the given long seed, passing it once through the (decent-quality and very fast)ThrustAltRNG
algorithm.static float
reversedIntBitsToFloat(int bits)
Reverses the byte order ofbits
and converts that to a float.static double
setExponent(double value, int exponentBits)
Makes a modified version of value that uses the specified bits (up to 12) for its exponent and sign.static double
setSelectedByte(double value, int whichByte, byte newValue)
LikegetSelectedByte(double, int)
, this sets the byte at a selected position in the int representation of a double, then returns the double produced by the bit change.static float
setSelectedByte(float value, int whichByte, byte newValue)
LikegetSelectedByte(float, int)
, this sets the byte at a selected position in the int representation of a float, then returns the float produced by the bit change.static double
sin(double radians)
A fairly-close approximation ofMath.sin(double)
that can be significantly faster (between 8x and 80x faster sin() calls in benchmarking; if you have access to libGDX you should consider its sometimes-more-precise and sometimes-faster MathUtils.sin() method.static float
sin(float radians)
A fairly-close approximation ofMath.sin(double)
that can be significantly faster (between 8x and 80x faster sin() calls in benchmarking, and both takes and returns floats; if you have access to libGDX you should consider its more-precise and sometimes-faster MathUtils.sin() method.static double
sin_(double turns)
A variation onMath.sin(double)
that takes its input as a fraction of a turn instead of in radians; one turn is equal to 360 degrees or two*PI radians.static float
sin_(float turns)
A variation onMath.sin(double)
that takes its input as a fraction of a turn instead of in radians (it also takes and returns a float); one turn is equal to 360 degrees or two*PI radians.static float
sinDegrees(float degrees)
A fairly-close approximation ofMath.sin(double)
that can be significantly faster (between 8x and 80x faster sin() calls in benchmarking, and both takes and returns floats; if you have access to libGDX, you should consider its more-precise and sometimes-faster MathUtils.sinDeg() method.static double
sway(double value)
Limited-use; takes any double and produces a double in the -1 to 1 range, with a graph of input to output that looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the input is halfway between two integers, smoothly curving at any points between those extremes.static float
sway(float value)
Limited-use; takes any float and produces a float in the -1f to 1f range, with a graph of input to output that looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the input is halfway between two integers, smoothly curving at any points between those extremes.static float
swayAngleRandomized(long seed, float value)
A 1D "noise" method that produces smooth transitions likesway(float)
, but also wrapping around at pi * 2 so this can be used to get smoothly-changing random angles.static double
swayRandomized(int seed, double value)
A variant onswayRandomized(long, double)
that takes an int seed instead of a long, and is optimized for usage on GWT.static float
swayRandomized(int seed, float value)
A variant onswayRandomized(long, float)
that takes an int seed instead of a long, and is optimized for usage on GWT.static double
swayRandomized(long seed, double value)
A mix of the smooth transitions ofsway(double)
with (seeded) random peaks and valleys between -1.0 and 1.0 (both exclusive).static float
swayRandomized(long seed, float value)
A mix of the smooth transitions ofsway(float)
with (seeded) random peaks and valleys between -1f and 1f (both exclusive).static double
swayTight(double value)
Limited-use; takes any double and produces a double in the 0.0 to 1.0 range, with a graph of input to output that looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the input is halfway between two integers, smoothly curving at any points between those extremes.static float
swayTight(float value)
Limited-use; takes any float and produces a float in the 0f to 1f range, with a graph of input to output that looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the input is halfway between two integers, smoothly curving at any points between those extremes.static double
zigzag(double value)
Limited-use; takes any double and produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and down through the range.static float
zigzag(float value)
Limited-use; takes any float and produces a float in the -1f to 1f range, with similar inputs producing close to a consistent rate of up and down through the range.
-
Constructor Details
-
NumberTools
public NumberTools()
-
-
Method Details
-
doubleToLongBits
Identical toDouble.doubleToLongBits(double)
on desktop; optimized on GWT. When compiling to JS via GWT, there is no way to distinguish NaN values with different bits but that are still NaN, so this doesn't try to somehow permit that. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not supporting them. JS typed arrays support double, but not long, so this needs to compose a long from two ints, which means the double-to/from-long conversions aren't as fast as float-to/from-int conversions.- Parameters:
value
- adouble
floating-point number.- Returns:
- the bits that represent the floating-point number.
-
doubleToRawLongBits
Identical toDouble.doubleToLongBits(double)
on desktop (note, notDouble.doubleToRawLongBits(double)
); optimized on GWT. When compiling to JS via GWT, there is no way to distinguish NaN values with different bits but that are still NaN, so this doesn't try to somehow permit that. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not supporting them. JS typed arrays support double, but not long, so this needs to compose a long from two ints, which means the double-to/from-long conversions aren't as fast as float-to/from-int conversions.- Parameters:
value
- adouble
floating-point number.- Returns:
- the bits that represent the floating-point number.
-
longBitsToDouble
Identical toDouble.longBitsToDouble(long)
on desktop; optimized on GWT. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not supporting them. JS typed arrays support double, but not long, so this needs to compose a long from two ints, which means the double-to/from-long conversions aren't as fast as float-to/from-int conversions.- Parameters:
bits
- a long.- Returns:
- the
double
floating-point value with the same bit pattern.
-
doubleToLowIntBits
Convertsvalue
to a long and gets the lower 32 bits of that long, as an int.- Parameters:
value
- adouble
precision floating-point number.- Returns:
- the lower half of the bits that represent the floating-point number, as an int.
-
doubleToHighIntBits
Convertsvalue
to a long and gets the upper 32 bits of that long, as an int.- Parameters:
value
- adouble
precision floating-point number.- Returns:
- the upper half of the bits that represent the floating-point number, as an int.
-
doubleToMixedIntBits
Convertsvalue
to a long and gets the XOR of its upper and lower 32-bit sections. Useful for numerical code where a 64-bit double needs to be reduced to a 32-bit value with some hope of keeping different doubles giving different ints.- Parameters:
value
- adouble
precision floating-point number.- Returns:
- the XOR of the lower and upper halves of the bits that represent the floating-point number.
-
setExponent
Makes a modified version of value that uses the specified bits (up to 12) for its exponent and sign. Meant for some specific cases, like adjusting the exponent on an unknown double to the 1.0 to 2.0 range (which would pass 0x3ff for exponentBits). If you have a double from 1.0 to 2.0, you can subtract 1.0 from it to get the often-desirable 0.0-1.0 range. Other common cases are 0x400, which adjusts to between 2.0 and 4.0 (subtracting 3.0 from this gives the -1.0 to 1.0 range, useful for noise), and 0xBFF, which adjusts to between -2.0 and -1.0. For the last case, you might think that -0x3ff would work, but sadly it doesn't. You can useexponentBits |= 0x800
to set the sign bit to negative, orexponentBits &= 0x7ff
for positive.- Parameters:
value
- a double that will have its sign and exponent set to the specified bitsexponentBits
- the bits to use for the sign and exponent section of the returned modification of value- Returns:
- the double produced by keeping the significand of value but changing its exponent and sign as given
-
getSelectedByte
Gets an 8-bit section of the given doublevalue
, usingwhichByte
to select whether this should return byte 0 (least significant), 1, 2, and so on up to 7 (most significant).- Parameters:
value
- a floatwhichByte
- an int that will be used to select the byte to take from value (any int is allowed, only the bottom 3 bits are used to select)- Returns:
- the selected byte from the given float
-
setSelectedByte
LikegetSelectedByte(double, int)
, this sets the byte at a selected position in the int representation of a double, then returns the double produced by the bit change. UseswhichByte
to select whether this should set byte 0 (least significant), 1, 2, and so on up to 7 (most significant).newValue
is a byte.- Parameters:
value
- a doublewhichByte
- an int that will be used to select the byte to take from value (any int is allowed, only the bottom 3 bits are used to select)newValue
- a byte that will be placed into the returned double's bits at the selected position- Returns:
- a double that results from changing the bits at the selected position to match newValue
-
bounce
Very limited-use; takes any double and produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and down through the range. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent sudden "jumps" in noise value.- Parameters:
value
- any double- Returns:
- a double from -1.0 (inclusive) to 1.0 (exclusive)
-
bounce
Very limited-use; takes any double and produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and down through the range. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent sudden "jumps" in noise value.- Parameters:
value
- any double- Returns:
- a double from -1.0 (inclusive) to 1.0 (exclusive)
-
bounce
Very limited-use; takes the significand bits of a double, represented as a long of which this uses 52 bits, and produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and down through the range. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent sudden "jumps" in noise value.- Parameters:
value
- any long; only the lower 52 bits will be used- Returns:
- a double from -1.0 (inclusive) to 1.0 (exclusive)
-
bounce
Very limited-use; takes the significand bits of a double, represented as a pair of intsvalueLow
andvalueHigh
, using all bits in valueLow and the least-significant 20 bits of valueHigh, and produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and down through the range. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent sudden "jumps" in noise value.- Parameters:
valueLow
- any int; all bits will be used as the less-significant bits of the significandvalueHigh
- any int; only the bottom 20 bits will be used as the more-significant bits of the significand- Returns:
- a double from -1.0 (inclusive) to 1.0 (exclusive)
-
zigzag
Limited-use; takes any double and produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and down through the range. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent sudden "jumps" in noise value. It is very similar tobounce(double)
, but unlike bounce() this will maintain a continuous rate regardless of the magnitude of its input. An input of any even number should produce something very close to -1.0, any odd number should produce something very close to 1.0, and any number halfway between two incremental integers (like 8.5 or -10.5) should produce 0.0 or a very small fraction. This method is closely related tosway(double)
, which will smoothly curve its output to produce more values that are close to -1 or 1.- Parameters:
value
- any double- Returns:
- a double from -1.0 (inclusive) to 1.0 (inclusive)
-
zigzag
Limited-use; takes any float and produces a float in the -1f to 1f range, with similar inputs producing close to a consistent rate of up and down through the range. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent sudden "jumps" in noise value. It is very similar tobounce(float)
, but unlike bounce() this will maintain a continuous rate regardless of the magnitude of its input. An input of any even number should produce something very close to -1f, any odd number should produce something very close to 1f, and any number halfway between two incremental integers (like 8.5f or -10.5f) should produce 0f or a very small fraction. This method is closely related tosway(float)
, which will smoothly curve its output to produce more values that are close to -1 or 1.- Parameters:
value
- any float- Returns:
- a float from -1f (inclusive) to 1f (inclusive)
-
sway
Limited-use; takes any double and produces a double in the -1 to 1 range, with a graph of input to output that looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the input is halfway between two integers, smoothly curving at any points between those extremes. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent both sudden "jumps" in noise value and "cracks" where a line takes a sudden jagged movement at an angle. It is very similar tobounce(double)
andzigzag(double)
, but unlike bounce() this will maintain its frequency of returning max or min values, regardless of the magnitude of its input (as long as there is enough floating-point precision to represent changes smaller than 1.0), and unlike zigzag() this will smooth its path. An input of any even number should produce something very close to -1.0, any odd number should produce something very close to 1.0, and any number halfway between two incremental integers (like 8.5 or -10.5) should produce 0.0 or a very small fraction. In the (unlikely) event that this is given a double that is too large to represent many or any non-integer values, this will simply return -1.0 or 1.0.- Parameters:
value
- any double other than NaN or infinite values; extremely large values can't work properly- Returns:
- a double from -1.0 (inclusive) to 1.0 (inclusive)
-
sway
Limited-use; takes any float and produces a float in the -1f to 1f range, with a graph of input to output that looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the input is halfway between two integers, smoothly curving at any points between those extremes. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent both sudden "jumps" in noise value and "cracks" where a line takes a sudden jagged movement at an angle. It is very similar tobounce(float)
andzigzag(float)
, but unlike bounce() this will maintain its frequency of returning max or min values, regardless of the magnitude of its input (as long as there is enough floating-point precision to represent changes smaller than 1f), and unlike zigzag() this will smooth its path. An input of any even number should produce something very close to -1f, any odd number should produce something very close to 1f, and any number halfway between two incremental integers (like 8.5f or -10.5f) should produce 0f or a very small fraction. In the (unlikely) event that this is given a float that is too large to represent many or any non-integer values, this will simply return -1f or 1f.- Parameters:
value
- any float other than NaN or infinite values; extremely large values can't work properly- Returns:
- a float from -1f (inclusive) to 1f (inclusive)
-
swayTight
Limited-use; takes any float and produces a float in the 0f to 1f range, with a graph of input to output that looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the input is halfway between two integers, smoothly curving at any points between those extremes. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent both sudden "jumps" in noise value and "cracks" where a line takes a sudden jagged movement at an angle. It is very similar tobounce(float)
andzigzag(float)
, but unlike bounce() this will not change its frequency of returning max or min values, regardless of the magnitude of its input (as long as there is enough floating-point precision to represent changes smaller than 1f), and unlike zigzag() this will smooth its path. An input of any even number should produce something very close to 0f, any odd number should produce something very close to 1f, and any number halfway between two incremental integers (like 8.5f or -10.5f) should produce 0.5f. In the (unlikely) event that this is given a float that is too large to represent many or any non-integer values, this will simply return 0f or 1f. This version is called "Tight" because its range is tighter thansway(float)
.- Parameters:
value
- any float other than NaN or infinite values; extremely large values can't work properly- Returns:
- a float from 0f (inclusive) to 1f (inclusive)
-
swayTight
Limited-use; takes any double and produces a double in the 0.0 to 1.0 range, with a graph of input to output that looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the input is halfway between two integers, smoothly curving at any points between those extremes. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent both sudden "jumps" in noise value and "cracks" where a line takes a sudden jagged movement at an angle. It is very similar tobounce(double)
andzigzag(double)
, but unlike bounce() this will not change its frequency of returning max or min values, regardless of the magnitude of its input (as long as there is enough floating-point precision to represent changes smaller than 1.0), and unlike zigzag() this will smooth its path. An input of any even number should produce something very close to 0.0, any odd number should produce something very close to 1.0, and any number halfway between two incremental integers (like 8.5 or -10.5) should produce 0.5f. In the (unlikely) event that this is given a double that is too large to represent many or any non-integer values, this will simply return 0.0 or 1.0. This version is called "Tight" because its range is tighter thansway(double)
.- Parameters:
value
- any double other than NaN or infinite values; extremely large values can't work properly- Returns:
- a double from 0.0 (inclusive) to 1.0 (inclusive)
-
swayRandomized
A mix of the smooth transitions ofsway(double)
with (seeded) random peaks and valleys between -1.0 and 1.0 (both exclusive). The pattern this will produces will be completely different if the seed changes, and it is suitable for 1D noise. Uses a simple method of cubic interpolation between random values, where a random value is used without modification when given an integer forvalue
. Note that this uses a different type of interpolation thansway(double)
, which uses quintic (this causes swayRandomized() to produce more outputs in the mid-range and less at extremes; it is also slightly faster and simpler).
Performance note: HotSpot seems to be much more able to optimize swayRandomized(long, float) than swayRandomized(long, double), with the float version almost twice as fast after JIT warms up. On GWT, the reverse should be expected because floats must be emulated there.- Parameters:
seed
- a long seed that will determine the pattern of peaks and valleys this will generate as value changes; this should not change between callsvalue
- a double that typically changes slowly, by less than 1.0, with direction changes at integer inputs- Returns:
- a pseudo-random double between -1.0 and 1.0 (both exclusive), smoothly changing with value
-
swayRandomized
A mix of the smooth transitions ofsway(float)
with (seeded) random peaks and valleys between -1f and 1f (both exclusive). The pattern this will produces will be completely different if the seed changes, and it is suitable for 1D noise. Uses a simple method of cubic interpolation between random values, where a random value is used without modification when given an integer forvalue
. Note that this uses a different type of interpolation thansway(float)
, which uses quintic (this causes swayRandomized() to produce more outputs in the mid-range and less at extremes; it is also slightly faster and simpler).
Performance note: HotSpot seems to be much more able to optimize swayRandomized(long, float) than swayRandomized(long, double), with the float version almost twice as fast after JIT warms up. On GWT, the reverse should be expected because floats must be emulated there.- Parameters:
seed
- a long seed that will determine the pattern of peaks and valleys this will generate as value changes; this should not change between callsvalue
- a float that typically changes slowly, by less than 2.0, with direction changes at integer inputs- Returns:
- a pseudo-random float between -1f and 1f (both exclusive), smoothly changing with value
-
swayRandomized
A variant onswayRandomized(long, double)
that takes an int seed instead of a long, and is optimized for usage on GWT. Like the version with a long seed, this uses cubic interpolation between random peak or valley points; only the method of generating those random peaks and valleys has changed.- Parameters:
seed
- an int seed that will determine the pattern of peaks and valleys this will generate as value changes; this should not change between callsvalue
- a double that typically changes slowly, by less than 2.0, with direction changes at integer inputs- Returns:
- a pseudo-random double between -1.0 and 1.0 (both exclusive), smoothly changing with value
-
swayRandomized
A variant onswayRandomized(long, float)
that takes an int seed instead of a long, and is optimized for usage on GWT. Like the version with a long seed, this uses cubic interpolation between random peak or valley points; only the method of generating those random peaks and valleys has changed.- Parameters:
seed
- an int seed that will determine the pattern of peaks and valleys this will generate as value changes; this should not change between callsvalue
- a float that typically changes slowly, by less than 2.0, with direction changes at integer inputs- Returns:
- a pseudo-random float between -1f and 1f (both exclusive), smoothly changing with value
-
swayAngleRandomized
A 1D "noise" method that produces smooth transitions likesway(float)
, but also wrapping around at pi * 2 so this can be used to get smoothly-changing random angles. Has (seeded) random peaks and valleys where it slows its range of change, but can return any value from 0 to 6.283185307179586f, or pi * 2. The pattern this will produces will be completely different if the seed changes, and the value is expected to be something other than an angle, like time. Uses a simple method of cubic interpolation between random values, where a random value is used without modification when given an integer forvalue
. Note that this uses a different type of interpolation thansway(float)
, which uses quintic (this causes swayAngleRandomized() to be slightly faster and simpler).- Parameters:
seed
- a long seed that will determine the pattern of peaks and valleys this will generate as value changes; this should not change between callsvalue
- a float that typically changes slowly, by less than 1.0, with possible direction changes at integer inputs- Returns:
- a pseudo-random float between 0f and 283185307179586f (both inclusive), smoothly changing with value and wrapping
-
floatToIntBits
Identical toFloat.floatToIntBits(float)
on desktop; optimized on GWT. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not supporting them.- Parameters:
value
- a floating-point number.- Returns:
- the bits that represent the floating-point number.
-
floatToRawIntBits
Identical toFloat.floatToIntBits(float)
on desktop (note, notFloat.floatToRawIntBits(float)
); optimized on GWT. When compiling to JS via GWT, there is no way to distinguish NaN values with different bits but that are still NaN, so this doesn't try to somehow permit that. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not supporting them.- Parameters:
value
- a floating-point number.- Returns:
- the bits that represent the floating-point number.
-
floatToReversedIntBits
Gets the bit representation of the given floatvalue
, but with reversed byte order. On desktop, this is equivalent to callingInteger.reverseBytes(Float.floatToIntBits(value))
, but it is implemented using typed arrays on GWT.- Parameters:
value
- a floating-point number- Returns:
- the bits that represent the floating-point number, with their byte order reversed from normal.
-
reversedIntBitsToFloat
Reverses the byte order ofbits
and converts that to a float. On desktop, this is equivalent to callingFloat.intBitsToFloat(Integer.reverseBytes(bits))
, but it is implemented using typed arrays on GWT.- Parameters:
bits
- an integer- Returns:
- the
float
floating-point value with the given bits using their byte order reversed from normal.
-
intBitsToFloat
Identical toFloat.intBitsToFloat(int)
on desktop; optimized on GWT. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not supporting them.- Parameters:
bits
- an integer.- Returns:
- the
float
floating-point value with the same bit pattern.
-
getSelectedByte
Gets an 8-bit section of the given floatvalue
, usingwhichByte
to select whether this should return byte 0 (least significant), 1, 2, or 3 (most significant).- Parameters:
value
- a floatwhichByte
- an int that will be used to select the byte to take from value (any int is allowed, only the bottom 2 bits are used to select)- Returns:
- the selected byte from the given float
-
setSelectedByte
LikegetSelectedByte(float, int)
, this sets the byte at a selected position in the int representation of a float, then returns the float produced by the bit change. UseswhichByte
to select whether this should set byte 0 (least significant), 1, 2, or 3 (most significant).newValue
is a byte.- Parameters:
value
- a floatwhichByte
- an int that will be used to select the byte to take from value (any int is allowed, only the bottom 2 bits are used to select)newValue
- a byte that will be placed into the returned float's bits at the selected position- Returns:
- a float that results from changing the bits at the selected position to match newValue
-
randomDouble
Generates a pseudo-random double between 0.0 (inclusive) and 1.0 (exclusive) using the given long seed, passing it once through the (decent-quality and very fast)ThrustAltRNG
algorithm.
Consider calling this withNumberTools.randomDouble(++seed)
for an optimal period of 2 to the 64 when repeatedly called, butNumberTools.randomDouble(seed += ODD_LONG)
will also work just fine if ODD_LONG is any odd-number long, positive or negative.- Parameters:
seed
- any long to be used as a seed- Returns:
- a pseudo-random double from 0.0 (inclusive) to 1.0 (exclusive)
-
randomSignedDouble
Generates a pseudo-random double between -1.0 (inclusive) and 1.0 (exclusive) using the given long seed, passing it once through the (decent-quality and very fast)ThrustAltRNG
algorithm.
Consider calling this withNumberTools.randomSignedDouble(++seed)
for an optimal period of 2 to the 64 when repeatedly called, butNumberTools.randomSignedDouble(seed += ODD_LONG)
will also work just fine if ODD_LONG is any odd-number long, positive or negative.- Parameters:
seed
- any long to be used as a seed- Returns:
- a pseudo-random double from 0.0 (inclusive) to 1.0 (exclusive)
-
randomFloat
Generates a pseudo-random float between 0f (inclusive) and 1f (exclusive) using the given long seed, passing it once through the (decent-quality and very fast)ThrustAltRNG
algorithm.
Consider calling this withNumberTools.randomFloat(++seed)
for an optimal period of 2 to the 64 when repeatedly called, butNumberTools.randomFloat(seed += ODD_LONG)
will also work just fine if ODD_LONG is any odd-number long, positive or negative.- Parameters:
seed
- any long to be used as a seed- Returns:
- a pseudo-random float from -1.0f (exclusive) to 1.0f (exclusive)
-
randomSignedFloat
Generates a pseudo-random float between -1f (inclusive) and 1f (exclusive) using the given long seed, passing it once through the (decent-quality and very fast)ThrustAltRNG
algorithm. This can be useful as a multiplier that has approximately equal likelihood of changing or leaving the sign of its multiplicand, and won't make the result larger (more significant) but will usually make it closer to 0.
Consider calling this withNumberTools.randomDouble(++seed)
for an optimal period of 2 to the 64 when repeatedly called, butNumberTools.randomDouble(seed += ODD_LONG)
will also work just fine if ODD_LONG is any odd-number long, positive or negative.- Parameters:
seed
- any long to be used as a seed- Returns:
- a pseudo-random float from -1.0f (exclusive) to 1.0f (exclusive)
-
randomFloatCurved
Generates a pseudo-random double between -1.0 (exclusive) and 1.0 (exclusive) with a distribution that has a strong central bias (around 0.0). Uses the given long seed, passing it once through the (decent-quality and very fast)ThrustAltRNG
algorithm. This produces a pseudo-random long, which this simply passes toformCurvedFloat(long)
, since it is already well-suited to generating a curved distribution.
Consider calling this withNumberTools.randomFloatCurved(++seed)
for an optimal period of 2 to the 64 when repeatedly called, butNumberTools.randomFloatCurved(seed += ODD_LONG)
will also work just fine if ODD_LONG is any odd-number long, positive or negative.- Parameters:
seed
- any int to be used as a seed- Returns:
- a pseudo-random double from -1.0 (exclusive) to 1.0 (exclusive), distributed on a curve centered on 0.0
-
formFloat
Given an int as a seed, this uses its least-significant 23 bits to produce a float between 0f (inclusive) and 1f (exclusive). This does not randomize the seed at all, and the upper 9 bits of the seed are ignored.- Parameters:
seed
- an int; only the bottom 23 bits will be used- Returns:
- a float between 0f (inclusive) and 1f (exclusive)
-
formSignedFloat
Given an int as a seed, this uses its least-significant 23 bits to produce a float between -1f (inclusive) and 1f (exclusive). This does not randomize the seed at all, and the upper 9 bits of the seed are ignored.- Parameters:
seed
- an int; only the bottom 23 bits will be used- Returns:
- a float between -1f (inclusive) and 1f (exclusive)
-
formDouble
Given a long as a seed, this uses its least-significant 52 bits to produce a double between 0 (inclusive) and 1 (exclusive). This does not randomize the seed at all, and the upper 12 bits of the seed are ignored.- Parameters:
seed
- a long; only the bottom 52 bits will be used- Returns:
- a double between 0 (inclusive) and 1 (exclusive)
-
formSignedDouble
Given a long as a seed, this uses its least-significant 52 bits to produce a double between -1 (inclusive) and 1 (exclusive). This does not randomize the seed at all, and the upper 12 bits of the seed are ignored.- Parameters:
seed
- a long; only the bottom 52 bits will be used- Returns:
- a double between -1 (inclusive) and 1 (exclusive)
-
formCurvedDouble
A different kind of determine-like method that expects to be given a random long and produces a random double with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f. The distribution for the values is similar to Irwin-Hall, and is frequently near 0 but not too-rarely near -1.0 or 1.0. It cannot produce 1.0, -1.0, or any values further from 0 than those bounds.- Parameters:
start
- a long, usually random, such as one produced by any RandomnessSource; all bits will be used- Returns:
- a deterministic double between -1.0 (exclusive) and 1.0 (exclusive); very likely to be close to 0.0
-
formCurvedDoubleTight
A different kind of determine-like method that expects to be given a random long and produces a random double with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach 0.0 and 1.0. The distribution for the values is similar to Irwin-Hall, and is frequently near 0 but not too-rarely near 0.0 or 1.0. It cannot produce 0.0, 1.0, or any values further from 0.5 than those bounds.- Parameters:
start
- a long, usually random, such as one produced by any RandomnessSource; all bits will be used- Returns:
- a deterministic double between 0.0 (exclusive) and 1.0 (exclusive); very likely to be close to 0.5
-
formCurvedFloat
A different kind of determine-like method that expects to be given a random long and produces a random float with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f. The distribution for the values is similar to Irwin-Hall, and is frequently near 0 but not too-rarely near -1f or 1f. It cannot produce 1f, -1f, or any values further from 0 than those bounds.- Parameters:
start
- a long, usually random, such as one produced by any RandomnessSource- Returns:
- a deterministic float between -1f (exclusive) and 1f (exclusive), that is very likely to be close to 0f
-
formCurvedFloat
A different kind of determine-like method that expects to be given random ints and produces a random float with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f. The distribution for the values is similar to Irwin-Hall, and is frequently near 0 but not too-rarely near -1f or 1f. It cannot produce 1f, -1f, or any values further from 0 than those bounds.- Parameters:
start1
- an int usually random, such as one produced by any RandomnessSourcestart2
- an int usually random, such as one produced by any RandomnessSource- Returns:
- a deterministic float between -1f (exclusive) and 1f (exclusive), that is very likely to be close to 0f
-
formCurvedFloat
A different kind of determine-like method that expects to be given a random int and produces a random float with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f. The distribution for the values is similar to Irwin-Hall, and is frequently near 0 but not too-rarely near -1f or 1f. It cannot produce 1f, -1f, or any values further from 0 than those bounds.- Parameters:
start
- an int, usually random, such as one produced by any RandomnessSource- Returns:
- a deterministic float between -1f (exclusive) and 1f (exclusive), that is very likely to be close to 0f
-
lowestOneBit
Returns an int value with at most a single one-bit, in the position of the lowest-order ("rightmost") one-bit in the specified int value. Returns zero if the specified value has no one-bits in its two's complement binary representation, that is, if it is equal to zero.
Identical toInteger.lowestOneBit(int)
, but super-sourced to act correctly on GWT. If you have GWT as a target and do bit manipulation work, double-check everything! An int can be higher thanInteger.MAX_VALUE
or lower thanInteger.MIN_VALUE
on GWT, without actually being a long (internally it's a double). This is especially relevant for the overload of this method that takes and returns a long;Long.lowestOneBit(long)
does not provide correct results for certain inputs on GWT, such as -17592186044416L, which it mysteriously returns 0L on, so you should uselowestOneBit(long)
.- Parameters:
num
- the value whose lowest one bit is to be computed- Returns:
- an int value with a single one-bit, in the position of the lowest-order one-bit in the specified value, or zero if the specified value is itself equal to zero.
-
lowestOneBit
Returns an long value with at most a single one-bit, in the position of the lowest-order ("rightmost") one-bit in the specified long value. Returns zero if the specified value has no one-bits in its two's complement binary representation, that is, if it is equal to zero.
Identical toLong.lowestOneBit(long)
, but super-sourced to act correctly on GWT. If you have GWT as a target and do bit manipulation work, double-check everything! An int can be higher thanInteger.MAX_VALUE
or lower thanInteger.MIN_VALUE
on GWT, without actually being a long (internally it's a double). This is especially relevant for this overload (for longs more so than for ints);Long.lowestOneBit(long)
does not provide correct results for certain inputs on GWT, such as -17592186044416L, which it mysteriously returns 0L on, so you should use this method.- Parameters:
num
- the value whose lowest one bit is to be computed- Returns:
- a long value with a single one-bit, in the position of the lowest-order one-bit in the specified value, or zero if the specified value is itself equal to zero.
-
sin
A fairly-close approximation ofMath.sin(double)
that can be significantly faster (between 8x and 80x faster sin() calls in benchmarking; if you have access to libGDX you should consider its sometimes-more-precise and sometimes-faster MathUtils.sin() method. Because this method doesn't rely on a lookup table, where libGDX's MathUtils does, applications that have a bottleneck on memory may perform better with this method than with MathUtils. Takes the same arguments Math.sin() does, so one angle in radians, which may technically be any double (but this will lose precision on fairly large doubles, such as those that are larger thanLong.MAX_VALUE
, because those doubles themselves will lose precision at that scale). This is closely related tosway(double)
, but the shape of the output when graphed is almost identical to sin(). The difference between the result of this method andMath.sin(double)
should be under 0.0011 at all points between -pi and pi, with an average difference of about 0.0005; not all points have been checked for potentially higher errors, though.
The error for this double version is extremely close to the float version,sin(float)
, so you should choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion between float and double takes about as long as this method normally takes to run (or longer), so if you have floats you should usually use methods that take floats (or return floats, if assigning the result to a float), and likewise for doubles.
Unlike in previous versions of this method, the sign of the input doesn't affect performance here, at least not by a measurable amount.
The technique for sine approximation is mostly from this archived DevMaster thread, with credit to "Nick". Changes have been made to accelerate wrapping from any double to the valid input range.- Parameters:
radians
- an angle in radians as a double, often from 0 to pi * 2, though not required to be.- Returns:
- the sine of the given angle, as a double between -1.0 and 1.0 (both inclusive)
-
cos
A fairly-close approximation ofMath.cos(double)
that can be significantly faster (between 8x and 80x faster cos() calls in benchmarking; if you have access to libGDX you should consider its sometimes-more-precise and sometimes-faster MathUtils.cos() method. Because this method doesn't rely on a lookup table, where libGDX's MathUtils does, applications that have a bottleneck on memory may perform better with this method than with MathUtils. Takes the same arguments Math.cos() does, so one angle in radians, which may technically be any double (but this will lose precision on fairly large doubles, such as those that are larger thanLong.MAX_VALUE
, because those doubles themselves will lose precision at that scale). This is closely related tosway(double)
, but the shape of the output when graphed is almost identical to cos(). The difference between the result of this method andMath.cos(double)
should be under 0.0011 at all points between -pi and pi, with an average difference of about 0.0005; not all points have been checked for potentially higher errors, though.
The error for this double version is extremely close to the float version,cos(float)
, so you should choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion between float and double takes about as long as this method normally takes to run (or longer), so if you have floats you should usually use methods that take floats (or return floats, if assigning the result to a float), and likewise for doubles.
Unlike in previous versions of this method, the sign of the input doesn't affect performance here, at least not by a measurable amount. The technique for cosine approximation is mostly from this archived DevMaster thread, with credit to "Nick". Changes have been made to accelerate wrapping from any double to the valid input range.- Parameters:
radians
- an angle in radians as a double, often from 0 to pi * 2, though not required to be.- Returns:
- the cosine of the given angle, as a double between -1.0 and 1.0 (both inclusive)
-
sin
A fairly-close approximation ofMath.sin(double)
that can be significantly faster (between 8x and 80x faster sin() calls in benchmarking, and both takes and returns floats; if you have access to libGDX you should consider its more-precise and sometimes-faster MathUtils.sin() method. Because this method doesn't rely on a lookup table, where libGDX's MathUtils does, applications that have a bottleneck on memory may perform better with this method than with MathUtils. Takes the same arguments Math.sin() does, so one angle in radians, which may technically be any float (but this will lose precision on fairly large floats, such as those that are larger thanInteger.MAX_VALUE
, because those floats themselves will lose precision at that scale). This is closely related tosway(float)
, but the shape of the output when graphed is almost identical to sin(). The difference between the result of this method andMath.sin(double)
should be under 0.0011 at all points between -pi and pi, with an average difference of about 0.0005; not all points have been checked for potentially higher errors, though.
The error for this float version is extremely close to the double version,sin(double)
, so you should choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion between float and double takes about as long as this method normally takes to run (or longer), so if you have floats you should usually use methods that take floats (or return floats, if assigning the result to a float), and likewise for doubles.
Unlike in previous versions of this method, the sign of the input doesn't affect performance here, at least not by a measurable amount.
The technique for sine approximation is mostly from this archived DevMaster thread, with credit to "Nick". Changes have been made to accelerate wrapping from any float to the valid input range.- Parameters:
radians
- an angle in radians as a float, often from 0 to pi * 2, though not required to be.- Returns:
- the sine of the given angle, as a float between -1f and 1f (both inclusive)
-
cos
A fairly-close approximation ofMath.cos(double)
that can be significantly faster (between 8x and 80x faster cos() calls in benchmarking, and both takes and returns floats; if you have access to libGDX you should consider its more-precise and sometimes-faster MathUtils.cos() method. Because this method doesn't rely on a lookup table, where libGDX's MathUtils does, applications that have a bottleneck on memory may perform better with this method than with MathUtils. Takes the same arguments Math.cos() does, so one angle in radians, which may technically be any float (but this will lose precision on fairly large floats, such as those that are larger thanInteger.MAX_VALUE
, because those floats themselves will lose precision at that scale). This is closely related tosway(float)
, but the shape of the output when graphed is almost identical to cos(). The difference between the result of this method andMath.cos(double)
should be under 0.0011 at all points between -pi and pi, with an average difference of about 0.0005; not all points have been checked for potentially higher errors, though.
The error for this float version is extremely close to the double version,cos(double)
, so you should choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion between float and double takes about as long as this method normally takes to run (or longer), so if you have floats you should usually use methods that take floats (or return floats, if assigning the result to a float), and likewise for doubles.
Unlike in previous versions of this method, the sign of the input doesn't affect performance here, at least not by a measurable amount.
The technique for cosine approximation is mostly from this archived DevMaster thread, with credit to "Nick". Changes have been made to accelerate wrapping from any float to the valid input range.- Parameters:
radians
- an angle in radians as a float, often from 0 to pi * 2, though not required to be.- Returns:
- the cosine of the given angle, as a float between -1f and 1f (both inclusive)
-
sinDegrees
A fairly-close approximation ofMath.sin(double)
that can be significantly faster (between 8x and 80x faster sin() calls in benchmarking, and both takes and returns floats; if you have access to libGDX, you should consider its more-precise and sometimes-faster MathUtils.sinDeg() method. Because this method doesn't rely on a lookup table, where libGDX's MathUtils does, applications that have a bottleneck on memory may perform better with this method than with MathUtils. Takes one angle in degrees, which may technically be any float (but this will lose precision on fairly large floats, such as those that are larger thanInteger.MAX_VALUE
, because those floats themselves will lose precision at that scale). This is closely related tosway(float)
, but the shape of the output when graphed is almost identical to sin(). The difference between the result of this method andMath.sin(double)
should be under 0.0011 at all points between -360 and 360, with an average difference of about 0.0005; not all points have been checked for potentially higher errors, though.
The error for this float version is extremely close to the double version,sin(double)
, so you should choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion between float and double takes about as long as this method normally takes to run (or longer), so if you have floats you should usually use methods that take floats (or return floats, if assigning the result to a float), and likewise for doubles.
Unlike in previous versions of this method, the sign of the input doesn't affect performance here, at least not by a measurable amount.
The technique for sine approximation is mostly from this archived DevMaster thread, with credit to "Nick". Changes have been made to accelerate wrapping from any float to the valid input range.- Parameters:
degrees
- an angle in degrees as a float, often from 0 to 360, though not required to be.- Returns:
- the sine of the given angle, as a float between -1f and 1f (both inclusive)
-
cosDegrees
A fairly-close approximation ofMath.cos(double)
that can be significantly faster (between 8x and 80x faster cos() calls in benchmarking, and both takes and returns floats; if you have access to libGDX, you should consider its more-precise and sometimes-faster MathUtils.cosDeg() method. Because this method doesn't rely on a lookup table, where libGDX's MathUtils does, applications that have a bottleneck on memory may perform better with this method than with MathUtils. Takes one angle in degrees, which may technically be any float (but this will lose precision on fairly large floats, such as those that are larger thanInteger.MAX_VALUE
, because those floats themselves will lose precision at that scale). This is closely related tosway(float)
, but the shape of the output when graphed is almost identical to cos(). The difference between the result of this method andMath.cos(double)
should be under 0.0011 at all points between -360 and 360, with an average difference of about 0.0005; not all points have been checked for potentially higher errors, though.
The error for this float version is extremely close to the double version,cos(double)
, so you should choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion between float and double takes about as long as this method normally takes to run (or longer), so if you have floats you should usually use methods that take floats (or return floats, if assigning the result to a float), and likewise for doubles.
Unlike in previous versions of this method, the sign of the input doesn't affect performance here, at least not by a measurable amount.
The technique for cosine approximation is mostly from this archived DevMaster thread, with credit to "Nick". Changes have been made to accelerate wrapping from any float to the valid input range.- Parameters:
degrees
- an angle in degrees as a float, often from 0 to pi * 2, though not required to be.- Returns:
- the cosine of the given angle, as a float between -1f and 1f (both inclusive)
-
sin_
A variation onMath.sin(double)
that takes its input as a fraction of a turn instead of in radians; one turn is equal to 360 degrees or two*PI radians. This can be useful as a building block for other measurements; to make a sine method that takes its input in grad (with 400 grad equal to 360 degrees), you would just divide the grad value by 400.0 (or multiply it by 0.0025) and pass it to this method. Similarly for binary degrees, also called brad (with 256 brad equal to 360 degrees), you would divide by 256.0 or multiply by 0.00390625 before passing that value here. The brad case is especially useful because you can use a byte for any brad values, and adding up those brad values will wrap correctly (256 brad goes back to 0) while keeping perfect precision for the results (you still divide by 256.0 when you pass the brad value to this method).
The error for this double version is extremely close to the float version,sin_(float)
, so you should choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion between float and double takes about as long as this method normally takes to run (or longer), so if you have floats you should usually use methods that take floats (or return floats, if assigning the result to a float), and likewise for doubles.
The technique for sine approximation is mostly from this archived DevMaster thread, with credit to "Nick". Changes have been made to accelerate wrapping from any double to the valid input range.- Parameters:
turns
- an angle as a fraction of a turn as a double, with 0.5 here equivalent to PI radians incos(double)
- Returns:
- the sine of the given angle, as a double between -1.0 and 1.0 (both inclusive)
-
cos_
A variation onMath.cos(double)
that takes its input as a fraction of a turn instead of in radians; one turn is equal to 360 degrees or two*PI radians. This can be useful as a building block for other measurements; to make a cosine method that takes its input in grad (with 400 grad equal to 360 degrees), you would just divide the grad value by 400.0 (or multiply it by 0.0025) and pass it to this method. Similarly for binary degrees, also called brad (with 256 brad equal to 360 degrees), you would divide by 256.0 or multiply by 0.00390625 before passing that value here. The brad case is especially useful because you can use a byte for any brad values, and adding up those brad values will wrap correctly (256 brad goes back to 0) while keeping perfect precision for the results (you still divide by 256.0 when you pass the brad value to this method).
The error for this double version is extremely close to the float version,cos_(float)
, so you should choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion between float and double takes about as long as this method normally takes to run (or longer), so if you have floats you should usually use methods that take floats (or return floats, if assigning the result to a float), and likewise for doubles.
The technique for cosine approximation is mostly from this archived DevMaster thread, with credit to "Nick". Changes have been made to accelerate wrapping from any double to the valid input range.- Parameters:
turns
- an angle as a fraction of a turn as a double, with 0.5 here equivalent to PI radians incos(double)
- Returns:
- the cosine of the given angle, as a double between -1.0 and 1.0 (both inclusive)
-
sin_
A variation onMath.sin(double)
that takes its input as a fraction of a turn instead of in radians (it also takes and returns a float); one turn is equal to 360 degrees or two*PI radians. This can be useful as a building block for other measurements; to make a sine method that takes its input in grad (with 400 grad equal to 360 degrees), you would just divide the grad value by 400.0 (or multiply it by 0.0025) and pass it to this method. Similarly for binary degrees, also called brad (with 256 brad equal to 360 degrees), you would divide by 256.0 or multiply by 0.00390625 before passing that value here. The brad case is especially useful because you can use a byte for any brad values, and adding up those brad values will wrap correctly (256 brad goes back to 0) while keeping perfect precision for the results (you still divide by 256.0 when you pass the brad value to this method).
The error for this float version is extremely close to the double version,sin_(double)
, so you should choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion between float and double takes about as long as this method normally takes to run (or longer), so if you have floats you should usually use methods that take floats (or return floats, if assigning the result to a float), and likewise for doubles.
The technique for sine approximation is mostly from this archived DevMaster thread, with credit to "Nick". Changes have been made to accelerate wrapping from any double to the valid input range.- Parameters:
turns
- an angle as a fraction of a turn as a float, with 0.5 here equivalent to PI radians incos(double)
- Returns:
- the sine of the given angle, as a float between -1.0 and 1.0 (both inclusive)
-
cos_
A variation onMath.cos(double)
that takes its input as a fraction of a turn instead of in radians (it also takes and returns a float); one turn is equal to 360 degrees or two*PI radians. This can be useful as a building block for other measurements; to make a cosine method that takes its input in grad (with 400 grad equal to 360 degrees), you would just divide the grad value by 400.0 (or multiply it by 0.0025) and pass it to this method. Similarly for binary degrees, also called brad (with 256 brad equal to 360 degrees), you would divide by 256.0 or multiply by 0.00390625 before passing that value here. The brad case is especially useful because you can use a byte for any brad values, and adding up those brad values will wrap correctly (256 brad goes back to 0) while keeping perfect precision for the results (you still divide by 256.0 when you pass the brad value to this method).
The error for this float version is extremely close to the float version,cos_(double)
, so you should choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion between float and double takes about as long as this method normally takes to run (or longer), so if you have floats you should usually use methods that take floats (or return floats, if assigning the result to a float), and likewise for doubles.
The technique for cosine approximation is mostly from this archived DevMaster thread, with credit to "Nick". Changes have been made to accelerate wrapping from any double to the valid input range.- Parameters:
turns
- an angle as a fraction of a turn as a float, with 0.5 here equivalent to PI radians incos(double)
- Returns:
- the cosine of the given angle, as a float between -1.0 and 1.0 (both inclusive)
-
atan2
Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 approximation. Maximum error is below 0.001 radians. Takes y and x (in that unusual order) as doubles, and returns the angle from the origin to that point in radians. It is about 5 times faster thanMath.atan2(double, double)
(roughly 17 ns instead of roughly 88 ns for Math, though the computer was under some load during testing). It is almost identical in speed to LibGDX' MathUtils approximation of the same method; MathUtils seems to have worse average error, though. Credit to StackExchange user njuffa, who gave this useful answer. This method changed from an earlier technique that was twice as fast but had very poor quality, enough to be visually noticeable. See alsoatan2_(double, double)
if you don't want a mess converting to degrees or some other measurement, since that method returns an angle from 0.0 (equal to 0 degrees) to 1.0 (equal to 360 degrees).- Parameters:
y
- y-component of the point to find the angle towards; note the parameter order is unusual by conventionx
- x-component of the point to find the angle towards; note the parameter order is unusual by convention- Returns:
- the angle to the given point, in radians as a double
-
atan2
Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 approximation. Maximum error is below 0.001 radians. Takes y and x (in that unusual order) as floats, and returns the angle from the origin to that point in radians. It is about 5 times faster thanMath.atan2(double, double)
(roughly 17 ns instead of roughly 88 ns for Math, though the computer was under some load during testing). It is almost identical in speed to LibGDX' MathUtils approximation of the same method; MathUtils seems to have worse average error, though. Credit to StackExchange user njuffa, who gave this useful answer. This method changed from an earlier technique that was twice as fast but had very poor quality, enough to be visually noticeable. See alsoatan2_(float, float)
if you don't want a mess converting to degrees or some other measurement, since that method returns an angle from 0f (equal to 0 degrees) to 1f (equal to 360 degrees).- Parameters:
y
- y-component of the point to find the angle towards; note the parameter order is unusual by conventionx
- x-component of the point to find the angle towards; note the parameter order is unusual by convention- Returns:
- the angle to the given point, in radians as a float
-
atan2_
Altered-range approximation of the frequently-used trigonometric method atan2, taking y and x positions as doubles and returning an angle measured in turns from 0.0 to 1.0 (inclusive), with one cycle over the range equivalent to 360 degrees or 2PI radians. You can multiply the angle by6.2831855f
to change to radians, or by360f
to change to degrees. Takes y and x (in that unusual order) as doubles. Will never return a negative number, which may help avoid costly floating-point modulus when you actually want a positive number. Credit to StackExchange user njuffa, who gave this useful answer. Note thatatan2(double, double)
returns an angle in radians and can return negative results, which may be fine for many tasks; these two methods are extremely close in implementation and speed.- Parameters:
y
- y-component of the point to find the angle towards; note the parameter order is unusual by conventionx
- x-component of the point to find the angle towards; note the parameter order is unusual by convention- Returns:
- the angle to the given point, as a double from 0.0 to 1.0, inclusive
-
atan2_
Altered-range approximation of the frequently-used trigonometric method atan2, taking y and x positions as floats and returning an angle measured in turns from 0.0f to 1.0f, with one cycle over the range equivalent to 360 degrees or 2PI radians. You can multiply the angle by6.2831855f
to change to radians, or by360f
to change to degrees. Takes y and x (in that unusual order) as floats. Will never return a negative number, which may help avoid costly floating-point modulus when you actually want a positive number. Credit to StackExchange user njuffa, who gave this useful answer. Note thatatan2(float, float)
returns an angle in radians and can return negative results, which may be fine for many tasks; these two methods are extremely close in implementation and speed.- Parameters:
y
- y-component of the point to find the angle towards; note the parameter order is unusual by conventionx
- x-component of the point to find the angle towards; note the parameter order is unusual by convention- Returns:
- the angle to the given point, as a float from 0.0f to 1.0f, inclusive
-
atan2Degrees
Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 approximation, and giving a result in degrees from -180 to 180. Maximum error is below 0.1 degrees. Takes y and x (in that unusual order) as doubles, and returns the angle from the origin to that point in degrees. It is about 5 times faster thanMath.atan2(double, double)
(roughly 17 ns instead of roughly 88 ns for Math, though the computer was under some load during testing). It is almost identical in speed to LibGDX' MathUtils approximation after converting to degrees; MathUtils seems to have worse average error, though. Credit to StackExchange user njuffa, who gave this useful answer.
See alsoatan2Degrees360(double, double)
, which is just like this but returns an angle from 0 to 360, instead of -180 to 180, in case negative angles are undesirable.- Parameters:
y
- y-component of the point to find the angle towards; note the parameter order is unusual by conventionx
- x-component of the point to find the angle towards; note the parameter order is unusual by convention- Returns:
- the angle to the given point, in degrees as a double
-
atan2Degrees
Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 approximation, and giving a result in degrees from -180 to 180. Maximum error is below 0.1 degrees. Takes y and x (in that unusual order) as floats, and returns the angle from the origin to that point in degrees. It is about 5 times faster thanMath.atan2(double, double)
(roughly 17 ns instead of roughly 88 ns for Math, though the computer was under some load during testing). It is almost identical in speed to LibGDX' MathUtils approximation after converting to degrees; MathUtils seems to have worse average error, though. Credit to StackExchange user njuffa, who gave this useful answer.
See alsoatan2Degrees360(float, float)
, which is just like this but returns an angle from 0 to 360, instead of -180 to 180, in case negative angles are undesirable.- Parameters:
y
- y-component of the point to find the angle towards; note the parameter order is unusual by conventionx
- x-component of the point to find the angle towards; note the parameter order is unusual by convention- Returns:
- the angle to the given point, in degrees as a float
-
atan2Degrees360
Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 approximation, and giving a result in degrees from 0 to 360. Maximum error is below 0.1 degrees. Takes y and x (in that unusual order) as doubles, and returns the angle from the origin to that point in degrees. It is about 5 times faster thanMath.atan2(double, double)
(roughly 17 ns instead of roughly 88 ns for Math, though the computer was under some load during testing). It is almost identical in speed to LibGDX' MathUtils approximation after converting to degrees; MathUtils seems to have worse average error, though. Credit to StackExchange user njuffa, who gave this useful answer.
See alsoatan2Degrees(double, double)
, which is just like this but returns an angle from -180 to 180, matchingMath.atan2(double, double)
's convention.- Parameters:
y
- y-component of the point to find the angle towards; note the parameter order is unusual by conventionx
- x-component of the point to find the angle towards; note the parameter order is unusual by convention- Returns:
- the angle to the given point, in degrees as a double
-
atan2Degrees360
Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 approximation, and giving a result in degrees from 0 to 360. Maximum error is below 0.1 degrees. Takes y and x (in that unusual order) as floats, and returns the angle from the origin to that point in degrees. It is about 5 times faster thanMath.atan2(double, double)
(roughly 17 ns instead of roughly 88 ns for Math, though the computer was under some load during testing). It is almost identical in speed to LibGDX' MathUtils approximation after converting to degrees; MathUtils seems to have worse average error, though. Credit to StackExchange user njuffa, who gave this useful answer.
See alsoatan2Degrees(float, float)
, which is just like this but returns an angle from -180 to 180, matchingMath.atan2(double, double)
's convention.- Parameters:
y
- y-component of the point to find the angle towards; note the parameter order is unusual by conventionx
- x-component of the point to find the angle towards; note the parameter order is unusual by convention- Returns:
- the angle to the given point, in degrees as a float
-
asin
Arc sine approximation with very low error, based on a simplified version ofatan2(double, double)
. This method is usually much faster thanMath.asin(double)
, but is somewhat less precise than Math's implementation). It is currently more precise than libGDX's approximation in their MathUtils, but this isn't quite as fast; the difference in precision is hard to spot but can be noticeable in some usage.- Parameters:
n
- an input to the inverse sine function, from -1 to 1 inclusive- Returns:
- an output from the inverse sine function, from PI/-2.0 to PI/2.0 inclusive.
-
asin
Arc sine approximation with very low error, based on a simplified version ofatan2(float, float)
. This method is usually much faster thanMath.asin(double)
, but is somewhat less precise than Math's implementation). It is currently more precise than libGDX's approximation in their MathUtils, but this isn't quite as fast; the difference in precision is hard to spot but can be noticeable in some usage.- Parameters:
n
- an input to the inverse sine function, from -1 to 1 inclusive- Returns:
- an output from the inverse sine function, from PI/-2.0 to PI/2.0 inclusive.
-
acos
Arc cosine approximation with very low error, based on a simplified version ofatan2(double, double)
. This method is usually much faster thanMath.acos(double)
, but is somewhat less precise than Math's implementation). It is currently more precise than libGDX's approximation in their MathUtils, but this isn't quite as fast; the difference in precision is hard to spot but can be noticeable in some usage.- Parameters:
n
- an input to the inverse cosine function, from -1 to 1 inclusive- Returns:
- an output from the inverse cosine function, from 0 to PI inclusive.
-
acos
Arc cosine approximation with very low error, based on a simplified version ofatan2(float, float)
. This method is usually much faster thanMath.acos(double)
, but is somewhat less precise than Math's implementation). It is currently more precise than libGDX's approximation in their MathUtils, but this isn't quite as fast; the difference in precision is hard to spot but can be noticeable in some usage.- Parameters:
n
- an input to the inverse cosine function, from -1 to 1 inclusive- Returns:
- an output from the inverse cosine function, from 0 to PI inclusive.
-
asin_
Inverse sine function (arcsine) but with output measured in turns instead of radians. Possible results for this range from 0.75 (inclusive) to 1.0 (exclusive), and continuing past that to 0.0 (inclusive) to 0.25 (inclusive).
This method is extremely similar to the non-turn approximation.- Parameters:
n
- a double from -1.0 to 1.0 (both inclusive), usually the output of sin_() or cos_()- Returns:
- one of the values that would produce
n
if it were passed tosin_(double)
-
acos_
Inverse cosine function (arccos) but with output measured in turns instead of radians. Possible results for this range from 0.0 (inclusive) to 0.5 (inclusive).
This method is extremely similar to the non-turn approximation.- Parameters:
n
- a double from -1.0 to 1.0 (both inclusive), usually the output of sin_() or cos_()- Returns:
- one of the values that would produce
n
if it were passed tocos_(double)
-
asin_
Inverse sine function (arcsine) but with output measured in turns instead of radians. Possible results for this range from 0.75f (inclusive) to 1.0f (exclusive), and continuing past that to 0.0f (inclusive) to 0.25f (inclusive).
This method is extremely similar to the non-turn approximation.- Parameters:
n
- a float from -1.0f to 1.0f (both inclusive), usually the output of sin_() or cos_()- Returns:
- one of the values that would produce
n
if it were passed tosin_(float)
-
acos_
Inverse cosine function (arccos) but with output measured in turns instead of radians. Possible results for this range from 0.0f (inclusive) to 0.5f (inclusive).
This method is extremely similar to the non-turn approximation.- Parameters:
n
- a float from -1.0f to 1.0f (both inclusive), usually the output of sin_() or cos_()- Returns:
- one of the values that would produce
n
if it were passed tocos_(float)
-