Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

define machine epsilon constants #9

Merged
merged 1 commit into from Aug 8, 2022

Conversation

jmcwilliams403
Copy link
Contributor

These are the IEEE-prescribed values already used in this library. I have assigned them names and also implemented the named versions in the Hasher class which already uses them. Their descriptions might need more elaboration regarding their properties.

These are the IEEE-prescribed values already used in this library. I have assigned them names and also implemented the named versions in the Hasher class which already uses them. Their descriptions might need more elaboration regarding their properties.
Copy link
Owner

@tommyettinger tommyettinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some docs that I don't think are quite accurate as they stand now. I do really like reusing the common values instead of having yet another magic number, heh. It would be really nice to mention in the docs that EPSILON is 2 to the -24, and EPSILON_D is 2 to the -53, which could save some source-diving.

@@ -314,7 +317,7 @@ public static int randomize3Bounded(long state, int bound) {
* @return a pseudo-random float between 0f (inclusive) and 1f (exclusive), determined by {@code state}
*/
public static float randomize1Float(long state) {
return ((((state = (((state * 0x632BE59BD9B4E019L) ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L)) ^ state >>> 27) * 0xAEF17502108EF2D9L) >>> 40) * 0x1p-24f;
return ((((state = (((state * 0x632BE59BD9B4E019L) ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L)) ^ state >>> 27) * 0xAEF17502108EF2D9L) >>> 40) * EPSILON;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's interesting that the multiplier used to produce the most valid zero-to-one floats with uniform spacing is also the machine epsilon; I am guessing that this isn't a coincidence.

@@ -53,6 +53,18 @@ private MathTools() {
* false-positive equivalence with very small inputs.
*/
public static final float FLOAT_ROUNDING_ERROR = 0x1p-20f; // was 0.000001f

/**
* The smallest measurable difference between a given {@code float} value and a directly adjacent value.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is right; the smallest measurable difference varies a lot based on the magnitude of the floats, and would be measured as one ulp. This is, however, the smallest non-zero distance possible between two floats returned by Random#nextFloat(), if my math is right.


/**
* The smallest measurable difference between a given {@code float} value and a directly adjacent value.
* Useful for converting a 64-bit {@code long} value to a gradient between 0 and 1.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also a bit of a nit-pick here, this is useful for converting non-negative up-to-24-bit ints or longs to fit in a uniformly-spaced 0 to 1 range. It can work on more than just long, and it probably doesn't do what you want if you multiply an arbitrary (possibly negative) long by this.

public static final float EPSILON = 0x1p-24f;

/**
* The smallest measurable difference between a given {@code double} value and a directly adjacent value.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the comment about an ulp above applies here. This might be the smallest non-zero distance possible between two doubles returned by Random#nextDouble(), but Random specifically might not be so precise. All of the EnhancedRandom classes in juniper have a nextDouble() that matches this precision.

@tommyettinger tommyettinger merged commit 44d6f1a into tommyettinger:main Aug 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants