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

Improve large numbers initialization in test data #2324

Merged
merged 14 commits into from
Mar 31, 2023
72 changes: 48 additions & 24 deletions integration/shareddata/scalars.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ import (
"strings"
"time"

"github.com/FerretDB/FerretDB/internal/util/must"

"go.mongodb.org/mongo-driver/bson/primitive"
)

const (
doubleBig = float64(1 << 61) // 2305843009213693952.0
longBig = int64(1 << 61) // 2305843009213693952
doubleMaxPrec = float64(1 << 53) // 9007199254740992.0
doubleMaxPrec = float64(1<<53 - 1) // 9007199254740991.0: largest double values that could be represented as integer exactly
doubleBig = float64(1 << 61) // 2305843009213693952.0: some number larger than safe integer (doubleBig+1 == doubleBig)
longBig = int64(1 << 61) // 2305843009213693952: same as doubleBig but integer

// TODO https://github.com/FerretDB/FerretDB/issues/2321
)

// Scalars contain scalar values for tests.
Expand All @@ -48,7 +52,7 @@ var Scalars = &Values[string]{
"double-5": float64(math.MaxInt64),
"double-6": float64(math.MaxInt64 + 1),
"double-7": 1.79769e+307,
"double-max-overflow": 9.223372036854776833e+18,
"double-max-overflow": 9.223372036854776833e+18, // TODO https://github.com/FerretDB/FerretDB/issues/2321
"double-max-overflow-verge": 9.223372036854776832e+18,
"double-min-overflow": -9.223372036854776833e+18,
"double-min-overflow-verge": -9.223372036854776832e+18,
Expand Down Expand Up @@ -134,20 +138,22 @@ var Doubles = &Values[string]{
"double-big-plus": doubleBig + 1,
"double-big-minus": doubleBig - 1,

// double max precision ~1<<53
"double-prec-max": doubleMaxPrec,
"double-prec-max-plus": doubleMaxPrec + 1,
"double-prec-max-minus": doubleMaxPrec - 1,
// double max precision ~1<<53 - 1
"double-prec-max": doubleMaxPrec,
"double-prec-max-plus": doubleMaxPrec + 1,
"double-prec-max-plus-two": doubleMaxPrec + 2,
"double-prec-max-minus": doubleMaxPrec - 1,

// negative double big values ~ -(1<<61)
"double-neg-big": -doubleBig,
"double-neg-big-plus": -(doubleBig + 1),
"double-neg-big-minus": -(doubleBig - 1),
"double-neg-big-plus": -doubleBig + 1,
rumyantseva marked this conversation as resolved.
Show resolved Hide resolved
"double-neg-big-minus": -doubleBig - 1,

// double min precision ~ -(1<<53 - 1)
"double-prec-min": -(doubleMaxPrec - 1),
"double-prec-min-plus": -(doubleMaxPrec - 1) + 1,
chilagrow marked this conversation as resolved.
Show resolved Hide resolved
"double-prec-min-minus": -(doubleMaxPrec - 1) - 1,
"double-prec-min": -doubleMaxPrec,
"double-prec-min-plus": -doubleMaxPrec + 1,
"double-prec-min-minus": -doubleMaxPrec - 1,
"double-prec-min-minus-two": -doubleMaxPrec - 2,
rumyantseva marked this conversation as resolved.
Show resolved Hide resolved

"double-null": nil,
"double-1": float64(math.MinInt64 - 1),
Expand Down Expand Up @@ -390,20 +396,22 @@ var Int64s = &Values[string]{
"int64-big-plus": longBig + 1,
"int64-big-minus": longBig - 1,

// long representation of double max precision ~1<<53
"int64-prec-max": int64(doubleMaxPrec),
"int64-prec-max-plus": int64(doubleMaxPrec) + 1,
"int64-prec-max-minus": int64(doubleMaxPrec) - 1,
// long representation of double max precision ~1<<53 - 1
"int64-prec-max": int64(doubleMaxPrec),
"int64-prec-max-plus": int64(doubleMaxPrec) + 1,
"int64-prec-max-plus-two": int64(doubleMaxPrec) + 2,
"int64-prec-max-minus": int64(doubleMaxPrec) - 1,

// negative long big values ~ -(1<<61)
"int64-neg-big": -longBig,
"int64-neg-big-plus": -(longBig + 1),
"int64-neg-big-minus": -(longBig - 1),

// long representation of double max precision ~ -(1<<53-1)
"int64-prec-min": -int64(doubleMaxPrec),
"int64-prec-min-plus": -(int64(doubleMaxPrec) - 1) + 1,
chilagrow marked this conversation as resolved.
Show resolved Hide resolved
"int64-prec-min-minus": -(int64(doubleMaxPrec) - 1) - 1,
"int64-neg-big-plus": -longBig + 1,
"int64-neg-big-minus": -longBig - 1,

// long representation of double min precision ~ -(1<<53 - 1)
"int64-prec-min": -int64(doubleMaxPrec),
"int64-prec-min-plus": -int64(doubleMaxPrec) + 1,
"int64-prec-min-minus": -int64(doubleMaxPrec) - 1,
"int64-prec-min-minus-two": -int64(doubleMaxPrec) - 2,
},
}

Expand Down Expand Up @@ -444,3 +452,19 @@ func tigrisSchema(typeString string) string {
}`
return strings.ReplaceAll(common, "%%type%%", typeString)
}

func init() {
// If any of those assumptions fails, it means that
// there's an issue related to precision double conversion.

must.BeTrue(float64(int64(doubleBig)) == doubleBig)
must.BeTrue(float64(int64(doubleBig)+1) == doubleBig)

must.BeTrue(float64(longBig) == doubleBig)

must.BeTrue(doubleMaxPrec != doubleMaxPrec+1)
must.BeTrue(doubleMaxPrec+1 == doubleMaxPrec+2)

must.BeTrue(-doubleMaxPrec != -doubleMaxPrec-1)
must.BeTrue(-doubleMaxPrec-1 == -doubleMaxPrec-2)
}
21 changes: 21 additions & 0 deletions integration/shareddata/shareddata_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2021 FerretDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package shareddata

import "testing"

func TestInit(t *testing.T) {
// nothing, just test init()
}
2 changes: 1 addition & 1 deletion internal/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import (
const MaxDocumentLen = 16 * 1024 * 1024 // 16 MiB = 16777216 bytes

// MaxSafeDouble is the maximum double value that can be represented precisely.
const MaxSafeDouble = float64(1 << 53) // 53bit mantissa = 9007199254740992
const MaxSafeDouble = float64(1<<53 - 1) // 52bit mantissa max value = 9007199254740991

// ScalarType represents scalar type.
type ScalarType interface {
Expand Down
10 changes: 10 additions & 0 deletions internal/util/must/must.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,13 @@ func NoError(err error) {
panic(err)
}
}

// BeTrue panic if the b is not true.
//
// Use that function only for static initialization, test code, or statemants that
// "can't" be false. When in doubt, don't.
func BeTrue(b bool) {
if !b {
panic("not true")
}
}