-
Notifications
You must be signed in to change notification settings - Fork 98
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
Instructions for porting to C# #189
Comments
@Dogwei -- I see your C# port at: Thanks, that's great -- that helped me get started with Ryu faster. I suggest some improvements. I see that currently your port doesn't use I also suggest eliminating (or at least reducing) the usage of unsafe pointers. These unsafe pointers are unnecessary. For Even when using the older .NET Framework 4.8 that doesn't support hmmm on second point, maybe you know all this already but you wanted to make a C# Ryu version that is as close as possible to the original plain-C source code, regardless of whether it does or doesn't achieve the performance goals when If that was your goal, I suggest you could make two versions: One that is a practical port to C# for real-world usage, and another version that is as close as possible to the plain-C source code. |
See also this suggestion from @Tornhoof to implement Ryu inside a future version of the .NET Framework 5.0: Consider implementing Ryu algorithm for double.ToString() #10939 |
Hi @verelpode. I intentionally picked a boring old languages, rather than an exciting new one, exactly because it is boring, close to assembly, and still pretty much universal. I'm happy to link to wherever you want to post your port or instructions for whatever modern language you feel like. However, this repo is going to stick with C. This report isn't directly actionable, so I will close it. Feel free to post the instructions (or even better, the source) somewhere and let me know. Thanks! |
It seems like Ulf Adams did a great job in creating Ryu, and he made impressive optimizations. The only downside is that the "master" version is the plain-C version instead of a modern language. Nevertheless it's great work.
I wrote up instructions for porting the "d2s.c" file to C#:
Firstly, eliminate all usage of the plain-C/prehistoric
memcpy
function. Change this:To:
Where
CopyFromDigitTable
is a new method (not in the original source code) implemented like this:To port the
mulShiftAll64
function, simplify and replace its confusing/unsafemul
pointer parameter with 2 simple reliable uint64 parameters namedmul_0
andmul_1
. Change this:To use two simple uint64 parameters named
mul_0
andmul_1
instead of the unsafemul
pointer:As you see above,
mulShiftAll64
invokesmulShift64
. Likewise changemulShift64
to have 2 parametersmul_0
andmul_1
instead of the unsafemul
pointer.Also,
mulShift64
invokesumul128
. Replaceumul128
invocations withSystem.Math.BigMul
:Swap "high" and "low" when replacing
umul128
withSystem.Math.BigMul
. i.e.System.Math.BigMul
andumul128
have exchanged meanings of the output parameter and return value ("low" and "high" are in swapped places).When the code invokes
mulShiftAll64
, update the invocation to pass the two newmul_0
andmul_1
parameters instead of themul
pointer: Change this:To:
Note the usage of the two-dimensional array, hence the comma in
DOUBLE_POW5_INV_SPLIT[q,0]
. This is much clearer and safer than the original confusingmul
pointer.To port the lookup table, change this:
To a C# two-dimensional array with comma in the
[,]
:To extract the float64/double to raw bits in a uint64, change this:
To use either
BitConverter.DoubleToInt64Bits
orCompilerServices.Unsafe.As
:Insert
unchecked { ... }
blocks covering the entire body of each function/method, to solve the problem of it throwing overflow exceptions whenever the C# program is compiled with overflow-checking enabled. In many places, this Ryu code is designed to deliberately cause and ignore overflows.Change every
char*
toSystem.Span<char>
. For example, change:To:
This Ryu code continues to work regardless of whether
char
is 8-bit or 16-bit.Change this:
To:
The
struct floating_decimal_64
should be changed toreadonly
:Only the
d2s_buffered_n
function/method modifies the fields insidestruct floating_decimal_64
but it is very easy to changed2s_buffered_n
to use local variables instead of the fields, followed by a final step of creating the instance offloating_decimal_64
at the end:Use
AggressiveInlining
where applicable:The text was updated successfully, but these errors were encountered: