-
Notifications
You must be signed in to change notification settings - Fork 14
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
Adds support for Ion Schema 2.0 ieee754_float constraint #213
Conversation
9b6e58b
to
f83fb9f
Compare
private val BINARY_16_PRECISION_RANGES = listOf( | ||
PrecisionInfo(0.0..1.0 / 16_384, interval = 1.0 / 16_777_216), // Subnormal numbers | ||
PrecisionInfo(1.0 / 16_384..1.0 / 8_192, interval = 1.0 / 16_777_216), | ||
PrecisionInfo(1.0 / 8_192..1.0 / 4_096, interval = 1.0 / 8_388_608), | ||
PrecisionInfo(1.0 / 4_096..1.0 / 2_048, interval = 1.0 / 4_194_304), | ||
PrecisionInfo(1.0 / 2_048..1.0 / 1_024, interval = 1.0 / 2_097_152), | ||
PrecisionInfo(1.0 / 1_024..1.0 / 512, interval = 1.0 / 1_048_576), | ||
PrecisionInfo(1.0 / 512..1.0 / 256, interval = 1.0 / 524_288), | ||
PrecisionInfo(1.0 / 256..1.0 / 128, interval = 1.0 / 262_144), | ||
PrecisionInfo(1.0 / 128..1.0 / 64, interval = 1.0 / 131_072), | ||
PrecisionInfo(1.0 / 64..1.0 / 32, interval = 1.0 / 65_536), | ||
PrecisionInfo(1.0 / 32..1.0 / 16, interval = 1.0 / 32_768), | ||
PrecisionInfo(1.0 / 16..1.0 / 8, interval = 1.0 / 16_384), | ||
PrecisionInfo(1.0 / 8..1.0 / 4, interval = 1.0 / 8_192), | ||
PrecisionInfo(1.0 / 4..1.0 / 2, interval = 1.0 / 4_096), | ||
PrecisionInfo(1.0 / 2..1.0, interval = 1.0 / 2_048), | ||
PrecisionInfo(1.0..2.0, interval = 1.0 / 1_024), | ||
PrecisionInfo(2.0..4.0, interval = 1.0 / 512), | ||
PrecisionInfo(4.0..8.0, interval = 1.0 / 256), | ||
PrecisionInfo(8.0..16.0, interval = 1.0 / 128), | ||
PrecisionInfo(16.0..32.0, interval = 1.0 / 64), | ||
PrecisionInfo(32.0..64.0, interval = 1.0 / 32), | ||
PrecisionInfo(64.0..128.0, interval = 1.0 / 16), | ||
PrecisionInfo(128.0..256.0, interval = 1.0 / 8), | ||
PrecisionInfo(256.0..512.0, interval = 1.0 / 4), | ||
PrecisionInfo(512.0..1_024.0, interval = 1.0 / 2), | ||
PrecisionInfo(1_024.0..2_048.0, interval = 1.0), | ||
PrecisionInfo(2_048.0..4_096.0, interval = 2.0), | ||
PrecisionInfo(4_096.0..8_192.0, interval = 4.0), | ||
PrecisionInfo(8_192.0..16_384.0, interval = 8.0), | ||
PrecisionInfo(16_384.0..32_768.0, interval = 16.0), | ||
PrecisionInfo(32_768.0..65_504.0, interval = 32.0), | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I played with this a bit to make sure I was understanding it :)
A couple alternate phrasings here, fwiw:
val BINARY_16_PRECISION_RANGES = sequence {
yield(PrecisionInfo( 0.0..2.0.pow(-14), interval = 2.0.pow(-24))) // Subnormal numbers
yieldAll((-14..14).asSequence().map {
PrecisionInfo(2.0.pow(it)..2.0.pow(it+1), interval = 2.0.pow(it-10))
})
// 65_504 is the largest precisely representable number
yield(PrecisionInfo(2.0.pow( 15)..65_504.0, interval = 2.0.pow( 5)))
}.toList()
or the equally verbose but also equivalent:
val BINARY_16_PRECISION_RANGES = listOf(
PrecisionInfo( 0.0..2.0.pow(-14), interval = 2.0.pow(-24)), // Subnormal numbers
PrecisionInfo(2.0.pow(-14)..2.0.pow(-13), interval = 2.0.pow(-24)),
PrecisionInfo(2.0.pow(-13)..2.0.pow(-12), interval = 2.0.pow(-23)),
PrecisionInfo(2.0.pow(-12)..2.0.pow(-11), interval = 2.0.pow(-22)),
PrecisionInfo(2.0.pow(-11)..2.0.pow(-10), interval = 2.0.pow(-21)),
PrecisionInfo(2.0.pow(-10)..2.0.pow( -9), interval = 2.0.pow(-20)),
PrecisionInfo(2.0.pow( -9)..2.0.pow( -8), interval = 2.0.pow(-19)),
PrecisionInfo(2.0.pow( -8)..2.0.pow( -7), interval = 2.0.pow(-18)),
PrecisionInfo(2.0.pow( -7)..2.0.pow( -6), interval = 2.0.pow(-17)),
PrecisionInfo(2.0.pow( -6)..2.0.pow( -5), interval = 2.0.pow(-16)),
PrecisionInfo(2.0.pow( -5)..2.0.pow( -4), interval = 2.0.pow(-15)),
PrecisionInfo(2.0.pow( -4)..2.0.pow( -3), interval = 2.0.pow(-14)),
PrecisionInfo(2.0.pow( -3)..2.0.pow( -2), interval = 2.0.pow(-13)),
PrecisionInfo(2.0.pow( -2)..2.0.pow( -1), interval = 2.0.pow(-12)),
PrecisionInfo(2.0.pow( -1)..2.0.pow( 0), interval = 2.0.pow(-11)),
PrecisionInfo(2.0.pow( 0)..2.0.pow( 1), interval = 2.0.pow(-10)),
PrecisionInfo(2.0.pow( 1)..2.0.pow( 2), interval = 2.0.pow( -9)),
PrecisionInfo(2.0.pow( 2)..2.0.pow( 3), interval = 2.0.pow( -8)),
PrecisionInfo(2.0.pow( 3)..2.0.pow( 4), interval = 2.0.pow( -7)),
PrecisionInfo(2.0.pow( 4)..2.0.pow( 5), interval = 2.0.pow( -6)),
PrecisionInfo(2.0.pow( 5)..2.0.pow( 6), interval = 2.0.pow( -5)),
PrecisionInfo(2.0.pow( 6)..2.0.pow( 7), interval = 2.0.pow( -4)),
PrecisionInfo(2.0.pow( 7)..2.0.pow( 8), interval = 2.0.pow( -3)),
PrecisionInfo(2.0.pow( 8)..2.0.pow( 9), interval = 2.0.pow( -2)),
PrecisionInfo(2.0.pow( 9)..2.0.pow( 10), interval = 2.0.pow( -1)),
PrecisionInfo(2.0.pow( 10)..2.0.pow( 11), interval = 2.0.pow( 0)),
PrecisionInfo(2.0.pow( 11)..2.0.pow( 12), interval = 2.0.pow( 1)),
PrecisionInfo(2.0.pow( 12)..2.0.pow( 13), interval = 2.0.pow( 2)),
PrecisionInfo(2.0.pow( 13)..2.0.pow( 14), interval = 2.0.pow( 3)),
PrecisionInfo(2.0.pow( 14)..2.0.pow( 15), interval = 2.0.pow( 4)),
PrecisionInfo(2.0.pow( 15)..65_504.0, interval = 2.0.pow( 5)),
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also suspect there's a fast generalizeable way to detect this from bits, using toRawBits()
and bit twiddling.
I looked at Float Toy and the manipulations of this gist, but ran out of energy and enthusiasm for reasoning through the corner cases.
I suspect that detecting "out of bounds" values in the double precision bit field is likely easier than straight conversion.
In any case, this was a fun diversion and I'm not at all asking for any changes here just sharing my thoughts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll create an issue for coming up with a generalizable solution. For now, I'm going to switch to the sequence-based factoring you suggested and add a link to the "Precision Limitations" table in the relevant wikipedia page.
f83fb9f
to
8f0cfa9
Compare
8f0cfa9
to
bca80bd
Compare
Issue #, if available:
#207
Description of changes:
ieee754_float
constraintIonSchemaTests_2_0
suite to include theieee754_float
test casesRelated PRs in ion-schema, ion-schema-tests, ion-schema-schemas:
Test cases: amazon-ion/ion-schema-tests#29
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.