@@ -86,86 +86,33 @@ public static YdbValue MakeUuid(Guid guid)
8686 new Ydb . Value { Low128 = low , High128 = high } ) ;
8787 }
8888
89- private static byte GetDecimalScale ( decimal value )
89+ public static YdbValue MakeDecimalWithPrecision ( decimal value , uint precision , uint scale )
9090 {
91- var bits = decimal . GetBits ( value ) ;
92- var flags = bits [ 3 ] ;
93- var scale = ( byte ) ( ( flags >> 16 ) & 0x7F ) ;
94- return scale ;
95- }
96-
97- private static uint GetDecimalPrecision ( decimal value )
98- {
99- var bits = decimal . GetBits ( value ) ;
100- value = new decimal ( lo : bits [ 0 ] , mid : bits [ 1 ] , hi : bits [ 2 ] , isNegative : false , scale : 0 ) ;
101-
102- var precision = 0u ;
103- while ( value != decimal . Zero )
104- {
105- value = Math . Round ( value / 10 ) ;
106- precision ++ ;
107- }
108-
109- return precision ;
110- }
91+ value *= 1.00000000000000000000000000000m ; // 29 zeros, max supported by c# decimal
92+ value = Math . Round ( value , ( int ) scale ) ;
11193
112- private static Ydb . Value MakeDecimalValue ( decimal value )
113- {
94+ var type = new Type { DecimalType = new DecimalType { Scale = scale , Precision = precision } } ;
11495 var bits = decimal . GetBits ( value ) ;
115-
116- var low64 = ( ( ulong ) ( uint ) bits [ 1 ] << 32 ) + ( uint ) bits [ 0 ] ;
117- var high64 = ( ulong ) ( uint ) bits [ 2 ] ;
96+ var lo = ( ( ulong ) bits [ 1 ] << 32 ) + ( uint ) bits [ 0 ] ;
97+ var hi = ( ulong ) bits [ 2 ] ;
11898
11999 unchecked
120100 {
121- // make value negative
122101 if ( value < 0 )
123102 {
124- low64 = ~ low64 ;
125- high64 = ~ high64 ;
103+ lo = ~ lo ;
104+ hi = ~ hi ;
126105
127- if ( low64 == ( ulong ) - 1L )
106+ if ( lo == ( ulong ) - 1L )
128107 {
129- high64 += 1 ;
108+ hi += 1 ;
130109 }
131110
132- low64 += 1 ;
111+ lo += 1 ;
133112 }
134113 }
135114
136- return new Ydb . Value
137- {
138- Low128 = low64 ,
139- High128 = high64
140- } ;
141- }
142-
143- public static YdbValue MakeDecimalWithPrecision ( decimal value , uint ? precision = null , uint ? scale = null )
144- {
145- var valueScale = GetDecimalScale ( value ) ;
146- var valuePrecision = GetDecimalPrecision ( value ) ;
147- scale ??= GetDecimalScale ( value ) ;
148- precision ??= valuePrecision ;
149-
150- if ( ( int ) valuePrecision - valueScale > ( int ) precision - scale )
151- {
152- throw new InvalidCastException (
153- $ "Decimal with precision ({ valuePrecision } , { valueScale } ) can't fit into ({ precision } , { scale } )") ;
154- }
155-
156- // multiply for fill value with trailing zeros
157- // ex: 123.45 -> 123.4500...00
158- value *= 1.00000000000000000000000000000m ; // 29 zeros, max supported by c# decimal
159- value = Math . Round ( value , ( int ) scale ) ;
160-
161- var type = new Type
162- {
163- DecimalType = new DecimalType { Scale = ( uint ) scale , Precision = ( uint ) precision }
164- } ;
165-
166- var ydbValue = MakeDecimalValue ( value ) ;
167-
168- return new YdbValue ( type , ydbValue ) ;
115+ return new YdbValue ( type , new Ydb . Value { Low128 = lo , High128 = hi } ) ;
169116 }
170117
171118 public static YdbValue MakeDecimal ( decimal value ) => MakeDecimalWithPrecision ( value , 22 , 9 ) ;
@@ -175,7 +122,8 @@ private static YdbValue MakeOptional(YdbValue value) =>
175122 new Type { OptionalType = new OptionalType { Item = value . _protoType } } ,
176123 value . TypeId != YdbTypeId . OptionalType
177124 ? value . _protoValue
178- : new Ydb . Value { NestedValue = value . _protoValue } ) ;
125+ : new Ydb . Value { NestedValue = value . _protoValue }
126+ ) ;
179127
180128 // TODO: MakeEmptyList with complex types
181129 public static YdbValue MakeEmptyList ( YdbTypeId typeId ) =>
0 commit comments