@@ -187,7 +187,7 @@ private static TTo ConvertByte<TTo>(byte value) where TTo : unmanaged
187187 }
188188 else if ( typeof ( TTo ) == typeof ( Half ) )
189189 {
190- // There isn't enough precision to convert from anything bigger than byte to Half, so we convert to float first.
190+ // There isn't enough precision to convert from byte to Half, so we convert to float first.
191191 float x = ConvertByte < float > ( value ) ;
192192 Half converted = ( Half ) x ;
193193 return Unsafe . As < Half , TTo > ( ref converted ) ;
@@ -327,7 +327,7 @@ private static TTo ConvertUInt16<TTo>(ushort value) where TTo : unmanaged
327327 }
328328 else if ( typeof ( TTo ) == typeof ( Half ) )
329329 {
330- // There isn't enough precision to convert from anything bigger than byte to Half, so we convert to float first.
330+ // There isn't enough precision to convert from ushort to Half, so we convert to float first.
331331 float x = ConvertUInt16 < float > ( value ) ;
332332 Half converted = ( Half ) x ;
333333 return Unsafe . As < Half , TTo > ( ref converted ) ;
@@ -470,14 +470,16 @@ private static TTo ConvertUInt32<TTo>(uint value) where TTo : unmanaged
470470 }
471471 else if ( typeof ( TTo ) == typeof ( Half ) )
472472 {
473- // There isn't enough precision to convert from anything bigger than byte to Half, so we convert to float first.
474- float x = ConvertUInt32 < float > ( value ) ;
473+ // There isn't enough precision to convert from uint to Half, so we convert to double first.
474+ double x = ConvertUInt32 < double > ( value ) ;
475475 Half converted = ( Half ) x ;
476476 return Unsafe . As < Half , TTo > ( ref converted ) ;
477477 }
478478 else if ( typeof ( TTo ) == typeof ( float ) )
479479 {
480- float converted = ( float ) value / ( float ) uint . MaxValue ;
480+ // There isn't enough precision to convert from uint to float, so we convert to double first.
481+ double x = ConvertUInt32 < double > ( value ) ;
482+ float converted = ( float ) x ;
481483 return Unsafe . As < float , TTo > ( ref converted ) ;
482484 }
483485 else if ( typeof ( TTo ) == typeof ( NFloat ) )
@@ -640,14 +642,16 @@ private static TTo ConvertUInt64<TTo>(ulong value) where TTo : unmanaged
640642 }
641643 else if ( typeof ( TTo ) == typeof ( Half ) )
642644 {
643- // There isn't enough precision to convert from anything bigger than byte to Half, so we convert to float first.
644- float x = ConvertUInt64 < float > ( value ) ;
645+ // There isn't enough precision to convert from ulong to Half, so we convert to double first.
646+ double x = ConvertUInt64 < double > ( value ) ;
645647 Half converted = ( Half ) x ;
646648 return Unsafe . As < Half , TTo > ( ref converted ) ;
647649 }
648650 else if ( typeof ( TTo ) == typeof ( float ) )
649651 {
650- float converted = ( float ) value / ( float ) ulong . MaxValue ;
652+ // There isn't enough precision to convert from ulong to float, so we convert to double first.
653+ double x = ConvertUInt64 < double > ( value ) ;
654+ float converted = ( float ) x ;
651655 return Unsafe . As < float , TTo > ( ref converted ) ;
652656 }
653657 else if ( typeof ( TTo ) == typeof ( NFloat ) )
@@ -785,14 +789,16 @@ private static TTo ConvertUInt128<TTo>(UInt128 value) where TTo : unmanaged
785789 }
786790 else if ( typeof ( TTo ) == typeof ( Half ) )
787791 {
788- // There isn't enough precision to convert from anything bigger than byte to Half, so we convert to float first.
789- float x = ConvertUInt128 < float > ( value ) ;
792+ // There isn't enough precision to convert from UInt128 to Half, so we convert to double first.
793+ double x = ConvertUInt128 < double > ( value ) ;
790794 Half converted = ( Half ) x ;
791795 return Unsafe . As < Half , TTo > ( ref converted ) ;
792796 }
793797 else if ( typeof ( TTo ) == typeof ( float ) )
794798 {
795- float converted = ( float ) value / ( float ) UInt128 . MaxValue ;
799+ // There isn't enough precision to convert from UInt128 to float, so we convert to double first.
800+ double x = ConvertUInt128 < double > ( value ) ;
801+ float converted = ( float ) x ;
796802 return Unsafe . As < float , TTo > ( ref converted ) ;
797803 }
798804 else if ( typeof ( TTo ) == typeof ( NFloat ) )
@@ -834,7 +840,7 @@ private static TTo ConvertHalf<TTo>(Half value) where TTo : unmanaged
834840 }
835841 else if ( typeof ( TTo ) == typeof ( byte ) )
836842 {
837- // We use float because it has enough precision to convert from Half to any integer type .
843+ // We use float because it has enough precision to convert from Half to byte .
838844 return ConvertSingle < TTo > ( ( float ) value ) ;
839845 }
840846 else if ( typeof ( TTo ) == typeof ( short ) )
@@ -844,7 +850,7 @@ private static TTo ConvertHalf<TTo>(Half value) where TTo : unmanaged
844850 }
845851 else if ( typeof ( TTo ) == typeof ( ushort ) )
846852 {
847- // We use float because it has enough precision to convert from Half to any integer type .
853+ // We use float because it has enough precision to convert from Half to ushort .
848854 return ConvertSingle < TTo > ( ( float ) value ) ;
849855 }
850856 else if ( typeof ( TTo ) == typeof ( int ) )
@@ -854,8 +860,8 @@ private static TTo ConvertHalf<TTo>(Half value) where TTo : unmanaged
854860 }
855861 else if ( typeof ( TTo ) == typeof ( uint ) )
856862 {
857- // We use float because it has enough precision to convert from Half to any integer type .
858- return ConvertSingle < TTo > ( ( float ) value ) ;
863+ // We use double because it has enough precision to convert from Half to uint .
864+ return ConvertDouble < TTo > ( ( double ) value ) ;
859865 }
860866 else if ( typeof ( TTo ) == typeof ( nint ) )
861867 {
@@ -890,8 +896,8 @@ private static TTo ConvertHalf<TTo>(Half value) where TTo : unmanaged
890896 }
891897 else if ( typeof ( TTo ) == typeof ( ulong ) )
892898 {
893- // We use float because it has enough precision to convert from Half to any integer type .
894- return ConvertSingle < TTo > ( ( float ) value ) ;
899+ // We use double because it has enough precision to convert from Half to ulong .
900+ return ConvertDouble < TTo > ( ( double ) value ) ;
895901 }
896902 else if ( typeof ( TTo ) == typeof ( Int128 ) )
897903 {
@@ -900,8 +906,8 @@ private static TTo ConvertHalf<TTo>(Half value) where TTo : unmanaged
900906 }
901907 else if ( typeof ( TTo ) == typeof ( UInt128 ) )
902908 {
903- // We use float because it has enough precision to convert from Half to any integer type .
904- return ConvertSingle < TTo > ( ( float ) value ) ;
909+ // We use double because it has enough precision to convert from Half to UInt128 .
910+ return ConvertDouble < TTo > ( ( double ) value ) ;
905911 }
906912 else if ( typeof ( TTo ) == typeof ( Half ) )
907913 {
@@ -975,10 +981,8 @@ private static TTo ConvertSingle<TTo>(float value) where TTo : unmanaged
975981 }
976982 else if ( typeof ( TTo ) == typeof ( uint ) )
977983 {
978- // x must be clamped because of rounding errors.
979- float x = value * ( float ) uint . MaxValue ;
980- uint converted = ( float ) uint . MaxValue < x ? uint . MaxValue : ( x > ( float ) uint . MinValue ? ( uint ) x : uint . MinValue ) ;
981- return Unsafe . As < uint , TTo > ( ref converted ) ;
984+ // We use double because it has enough precision to convert from float to uint.
985+ return ConvertDouble < TTo > ( ( double ) value ) ;
982986 }
983987 else if ( typeof ( TTo ) == typeof ( nint ) )
984988 {
@@ -1013,10 +1017,8 @@ private static TTo ConvertSingle<TTo>(float value) where TTo : unmanaged
10131017 }
10141018 else if ( typeof ( TTo ) == typeof ( ulong ) )
10151019 {
1016- // x must be clamped because of rounding errors.
1017- float x = value * ( float ) ulong . MaxValue ;
1018- ulong converted = ( float ) ulong . MaxValue < x ? ulong . MaxValue : ( x > ( float ) ulong . MinValue ? ( ulong ) x : ulong . MinValue ) ;
1019- return Unsafe . As < ulong , TTo > ( ref converted ) ;
1020+ // We use double because it has enough precision to convert from float to ulong.
1021+ return ConvertDouble < TTo > ( ( double ) value ) ;
10201022 }
10211023 else if ( typeof ( TTo ) == typeof ( Int128 ) )
10221024 {
@@ -1025,10 +1027,8 @@ private static TTo ConvertSingle<TTo>(float value) where TTo : unmanaged
10251027 }
10261028 else if ( typeof ( TTo ) == typeof ( UInt128 ) )
10271029 {
1028- // x must be clamped because of rounding errors.
1029- float x = value * ( float ) UInt128 . MaxValue ;
1030- UInt128 converted = ( float ) UInt128 . MaxValue < x ? UInt128 . MaxValue : ( x > ( float ) UInt128 . MinValue ? ( UInt128 ) x : UInt128 . MinValue ) ;
1031- return Unsafe . As < UInt128 , TTo > ( ref converted ) ;
1030+ // We use double because it has enough precision to convert from float to UInt128.
1031+ return ConvertDouble < TTo > ( ( double ) value ) ;
10321032 }
10331033 else if ( typeof ( TTo ) == typeof ( Half ) )
10341034 {
0 commit comments