Re: DMD: can't get extern __gshared to work right (vs. LDC)
On Friday, 8 February 2019 at 07:52:26 UTC, Kagamin wrote: AFAIK, export attribute doesn't do much on posix platforms. I created a minimal example and it definitely segfaults at runtime in the presence of "export" (on Mac, haven't tested linux). So it's required for Windows and silently evil for Mac... Any reason I shouldn't file a DMD bug for this?
Re: DMD: can't get extern __gshared to work right (vs. LDC)
On 08/02/2019 9:14 PM, DanielG wrote: On Friday, 8 February 2019 at 07:52:26 UTC, Kagamin wrote: AFAIK, export attribute doesn't do much on posix platforms. I created a minimal example and it definitely segfaults at runtime in the presence of "export" (on Mac, haven't tested linux). So it's required for Windows and silently evil for Mac... Any reason I shouldn't file a DMD bug for this? File, inconsistent behavior is inconsistent. Not good.
Re: Tricky DMD bug, but I have no idea how to report
On Friday, 8 February 2019 at 07:30:41 UTC, Vladimir Panteleev wrote: On Thursday, 7 February 2019 at 22:16:19 UTC, JN wrote: Does it also work for dub projects? It will work if you can put all the relevant D code in one directory, which is harder for Dub, as it likes to pull dependencies from all over the place. When "dub dustmite" is insufficient (as in this case), the safest way to proceed would be to build with dub in verbose mode, take note of the compiler command lines it's using, then put them in a shell script and all mentioned D files in one directory, then pass that to Dustmite. I will try. However, one last thing - in the example test scripts, it runs first with one compiler setting (or D version) and the second time with the other compiler setting (or D version). But it looks like the exit code of the first run is ignored anyway, so why run it?
Re: Tricky DMD bug, but I have no idea how to report
On Friday, 8 February 2019 at 09:28:48 UTC, JN wrote: I will try. However, one last thing - in the example test scripts, it runs first with one compiler setting (or D version) and the second time with the other compiler setting (or D version). But it looks like the exit code of the first run is ignored anyway, so why run it? With "set -e", the shell interpreter will exit the script with any command that fails (returns with non-zero status), unless it's in an "if" condition or such. I'll update the article to clarify it.
Re: Submenu Not Responding Until Second Click
On Thursday, 7 February 2019 at 08:41:29 UTC, Antonio Corbi wrote: Hi Ron, xrandr (and gui interfaces for it like arandr) are your friends here. xrandr -q -> shows your card outputs and then you can use xrandr + options to configure monitors. Or you can use arandr that will do that for you and will allow you to visually spatially-arrange your monitors. Antonio Thanks for the tip, Antonio. I'd never heard of xrandr or arandr. Must be new since I stopped paying attention a few years ago.
Re: DMD: can't get extern __gshared to work right (vs. LDC)
On Friday, 8 February 2019 at 09:19:12 UTC, rikki cattermole wrote: File, inconsistent behavior is inconsistent. Not good. done: https://issues.dlang.org/show_bug.cgi?id=19660
Re: Is it possible to modify shared struct array in a function.
On Friday, 8 February 2019 at 06:55:15 UTC, Jerry wrote: On Friday, 8 February 2019 at 04:51:08 UTC, Sudhi wrote: On Friday, 8 February 2019 at 04:30:23 UTC, Arun Chandrasekaran wrote: On Friday, 8 February 2019 at 04:13:39 UTC, Sudhi wrote: [...] Works fine for me with DMD64 D Compiler v2.083.1. https://run.dlang.io/is/RRM8GU My example code was wrong. Below is the right one. struct Company { string name; string location; } struct Racks { int number; int location; } struct Metadata { string name; Company[] companies; Racks[] racks; } struct Item { Metadata[] met; int count; } shared (Item) item; void main() { updateMetadata(); } void updateMetadata() { Company company; company.name = "Hello"; company.location = "Bangalore"; item.met.companies ~= company; import std.stdio: writeln; writeln(item); } https://run.dlang.io/is/iem0PY You have to cast away shared: auto loc_item = cast(Item) item; loc_item.met ~= m; item = cast(shared) loc_item; Just to be clear, this is not threadsafe and require a mutex if you do this other than as init in main. You do not need to cast away shared. You had a couple of issues with your `updateMetadata()` function. First of, `met` is an array, so you need to index it: your code `item.met.companies ~= company` becomes `item.met[0].companies ~= company`. This will compile, but throw a range error because you don't have any `Metadata` object in your `met` array. I have typed below the revised form of your function ``` void updateMetadata() { // create a Company instance. This must be shared shared Company company; company.name = "Hello"; company.location = "Bangalore"; // create a shared Metadata instance shared Metadata m; m.name = "m"; // append m to the array of meta item.met ~= m; // append the company to the array of companies, for a given meta item.met[0].companies ~= company; import std.stdio: writeln; writeln(item); } ``` The working version is at https://run.dlang.io/is/RvRKrU Cheers, Edi
Re: Submenu Not Responding Until Second Click
On Friday, 8 February 2019 at 10:03:03 UTC, Ron Tarrant wrote: On Thursday, 7 February 2019 at 08:41:29 UTC, Antonio Corbi wrote: Hi Ron, xrandr (and gui interfaces for it like arandr) are your friends here. xrandr -q -> shows your card outputs and then you can use xrandr + options to configure monitors. Or you can use arandr that will do that for you and will allow you to visually spatially-arrange your monitors. Antonio Thanks for the tip, Antonio. I'd never heard of xrandr or arandr. Must be new since I stopped paying attention a few years ago. No, xrandr has been around for a long time: https://www.x.org/wiki/Projects/XRandR/ It makes easier than xinerama to configure several monitors. For example when I start my xsession with an external monitor attached to the HDMI port, I switch-off the internal laptop panel and use only the external one, a small script like this does the trick: xrandr | grep "HDMI-1 conn" >/dev/null if [ $? = 0 ] then xrandr --output HDMI-1 --auto --primary --output LVDS-1 --off fi Those names like HDMI-1 or LVDS-1 are the ones that 'xrandr' or 'xrandr -q' show you. Depending on the driver/card combination they may change. Xrandr requires that your card driver supports it, nowadays it is the usual thing, but you'll have to check that. Arandr (there are others) simplify the configure task due to their GUI based interface, though I prefer the text based interface that xrandr offers. Antonio.
Memory reference that does not stop garbage collection.
I have observers and listeners. class Observer { Listener[] listeners; } class Listener {} The observers keep references to listeners, but I would like the GC to garbage collect listeners even if observers have references to it and remove the references in observers. I should be able to use `core.memory.GC.removeRange` right? class Observer { Listener[] listeners; this() { listeners = []; GC.removeRange(listeners.ptr); } } And in the deconstructor for listeners release the references in observers. How does that work if the listeners array gets reallocated when extending, do I just recall `removeRange` any time after an append? I am guessing I am not the first one to want this so I would rather not reinvent the wheel myself. I also do not want memory leaks. Thanks!
Re: Memory reference that does not stop garbage collection.
On Friday, 8 February 2019 at 15:42:13 UTC, Jonathan Levi wrote: I should be able to use `core.memory.GC.removeRange` right? That would leave dangling references in the array. You may be interested in this, but I have not used it myself: https://repo.or.cz/w/iv.d.git/blob/HEAD:/weakref.d
Re: Tricky DMD bug, but I have no idea how to report
On Friday, 8 February 2019 at 09:30:12 UTC, Vladimir Panteleev wrote: On Friday, 8 February 2019 at 09:28:48 UTC, JN wrote: I will try. However, one last thing - in the example test scripts, it runs first with one compiler setting (or D version) and the second time with the other compiler setting (or D version). But it looks like the exit code of the first run is ignored anyway, so why run it? With "set -e", the shell interpreter will exit the script with any command that fails (returns with non-zero status), unless it's in an "if" condition or such. I'll update the article to clarify it. I see. Dustmite helped. I had to convert it to windows batch, so my testscript ended up to be: dmd -O -inline -release -boundscheck=on -i app.d -m64 @IF %ERRORLEVEL% EQU 0 (ECHO No error found) ELSE (EXIT /B 1) @app | FINDSTR /C:"Object" @IF %ERRORLEVEL% EQU 0 (ECHO No error found) ELSE (EXIT /B 1) dmd -O -inline -release -boundscheck=off -i app.d -m64 @IF %ERRORLEVEL% EQU 0 (ECHO No error found) ELSE (EXIT /B 1) @app | FINDSTR /C:"null" @IF %ERRORLEVEL% EQU 0 (EXIT /B 0) ELSE (EXIT /B 1) I managed to greatly reduce the source code. I have filed a bug with the reduced testcase https://issues.dlang.org/show_bug.cgi?id=19662 .
Re: Tricky DMD bug, but I have no idea how to report
On Fri, Feb 08, 2019 at 09:23:40PM +, JN via Digitalmars-d-learn wrote: [...] > I managed to greatly reduce the source code. I have filed a bug with > the reduced testcase https://issues.dlang.org/show_bug.cgi?id=19662 . Haha, you were right! It's a compiler bug, another one of those nasty -O -inline bugs. Probably a backend codegen bug. Ran into one of those before; was pretty nasty. Fortunately it got fixed soon(ish) after I made noise about it in the forum. :-P T -- Don't drink and derive. Alcohol and algebra don't mix.
Re: Tricky DMD bug, but I have no idea how to report
On Friday, 8 February 2019 at 21:35:34 UTC, H. S. Teoh wrote: On Fri, Feb 08, 2019 at 09:23:40PM +, JN via Digitalmars-d-learn wrote: [...] I managed to greatly reduce the source code. I have filed a bug with the reduced testcase https://issues.dlang.org/show_bug.cgi?id=19662 . Haha, you were right! It's a compiler bug, another one of those nasty -O -inline bugs. Probably a backend codegen bug. Ran into one of those before; was pretty nasty. Fortunately it got fixed soon(ish) after I made noise about it in the forum. :-P T Luckily it's not a blocker for me, because it doesn't trigger on debug builds, and for release builds I can always use LDC, but still it's bugging me (pun intended).
Re: Tricky DMD bug, but I have no idea how to report
On Fri, Feb 08, 2019 at 09:42:11PM +, JN via Digitalmars-d-learn wrote: > On Friday, 8 February 2019 at 21:35:34 UTC, H. S. Teoh wrote: > > On Fri, Feb 08, 2019 at 09:23:40PM +, JN via Digitalmars-d-learn > > wrote: [...] > > > I managed to greatly reduce the source code. I have filed a bug > > > with the reduced testcase > > > https://issues.dlang.org/show_bug.cgi?id=19662 . > > > > Haha, you were right! It's a compiler bug, another one of those > > nasty -O -inline bugs. Probably a backend codegen bug. Ran into > > one of those before; was pretty nasty. Fortunately it got fixed > > soon(ish) after I made noise about it in the forum. :-P [...] > Luckily it's not a blocker for me, because it doesn't trigger on debug > builds, and for release builds I can always use LDC, but still it's > bugging me (pun intended). Pity I still can't reproduce the problem locally. Otherwise I would reduce it even more -- e.g., eliminate std.stdio dependency and have the program fail on assert(obj != null), and a bunch of other things to make it easier for compiler devs to analyze -- and perhaps look at the generated assembly to see what went wrong. If you have the time (and patience) to do that, it would greatly increase the chances of this being fixed in a timely way, since it would narrow down the bug even more so that it's easier to find in the dmd source code. T -- I see that you JS got Bach.
Re: Tricky DMD bug, but I have no idea how to report
On Friday, 8 February 2019 at 22:11:31 UTC, H. S. Teoh wrote: Pity I still can't reproduce the problem locally. Otherwise I would reduce it even more -- e.g., eliminate std.stdio dependency and have the program fail on assert(obj != null), and a bunch of other things to make it easier for compiler devs to analyze -- and perhaps look at the generated assembly to see what went wrong. If you have the time (and patience) to do that, it would greatly increase the chances of this being fixed in a timely way, since it would narrow down the bug even more so that it's easier to find in the dmd source code. T It seems to be a Windows 64-bit only thing. Anyway, I reduced the code further manually. It's very hard to reduce it any further. For example, removing the assignments in fromEulerAngles static method hides the bug. Likewise, replacing writeln with assert makes it work properly too.
Re: Tricky DMD bug, but I have no idea how to report
On Fri, Feb 08, 2019 at 10:45:39PM +, JN via Digitalmars-d-learn wrote: [...] > Anyway, I reduced the code further manually. It's very hard to reduce > it any further. For example, removing the assignments in > fromEulerAngles static method hides the bug. Likewise, replacing > writeln with assert makes it work properly too. Pity we couldn't get rid of std.stdio. It's a pretty big piece of code, and there are plenty of places where it may go wrong inside, even though we generally expect that the bug lies elsewhere. Oh well. Hopefully somebody else can dig into this and figure out what's going on. Hmm. I just glanced over the std.stdio code... it appears that somebody has added @trusted all over the place, probably just to get it to compile with @safe. That's kinda scary... somebody needs to vet this code carefully to make sure nothing fishy's going on in there! T -- For every argument for something, there is always an equal and opposite argument against it. Debates don't give answers, only wounded or inflated egos.
Re: Tricky DMD bug, but I have no idea how to report
On Friday, 8 February 2019 at 23:30:44 UTC, H. S. Teoh wrote: On Fri, Feb 08, 2019 at 10:45:39PM +, JN via Digitalmars-d-learn wrote: [...] Anyway, I reduced the code further manually. It's very hard to reduce it any further. For example, removing the assignments in fromEulerAngles static method hides the bug. Likewise, replacing writeln with assert makes it work properly too. Pity we couldn't get rid of std.stdio. It's a pretty big piece of code, and there are plenty of places where it may go wrong inside, even though we generally expect that the bug lies elsewhere. Oh well. Hopefully somebody else can dig into this and figure out what's going on. Hmm. I just glanced over the std.stdio code... it appears that somebody has added @trusted all over the place, probably just to get it to compile with @safe. That's kinda scary... somebody needs to vet this code carefully to make sure nothing fishy's going on in there! T I can replace it with core.stdc.stdio if it's any better. Looks like any attempt to do a check for "x is null" hides the bug. I tried assert(), also tried if (x is null) throw new Exception(...)
Re: Tricky DMD bug, but I have no idea how to report
On Fri, Feb 08, 2019 at 11:36:03PM +, JN via Digitalmars-d-learn wrote: > On Friday, 8 February 2019 at 23:30:44 UTC, H. S. Teoh wrote: [...] > > Pity we couldn't get rid of std.stdio. [...] > I can replace it with core.stdc.stdio if it's any better. Looks like > any attempt to do a check for "x is null" hides the bug. I tried > assert(), also tried if (x is null) throw new Exception(...) Aha! That's an important insight. It's almost certain that it's caused by a backend bug now. So testing the value perturbs the codegen code path enough to mask the bug / avoid the bug. I think from this point somebody who's familiar with the dmd backend ought to be able to track it down reasonably easily. (Unfortunately I'm completely unfamiliar with that part of the dmd code.) T -- In order to understand recursion you must first understand recursion.
Handling big FP numbers
Why is it that in C when I attribute the number 991234307654329925.7865 to a double it prints 991234299470108672. and in D it prints 9912342990. ? Apparently both languages cause a certain loss of precision(which is part of converting the decimal system into the binary system) but why is it that the results are different?
Re: Is it possible to modify shared struct array in a function.
On Friday, February 8, 2019 4:27:44 AM MST Eduard Staniloiu via Digitalmars- d-learn wrote: > On Friday, 8 February 2019 at 06:55:15 UTC, Jerry wrote: > > On Friday, 8 February 2019 at 04:51:08 UTC, Sudhi wrote: > >> On Friday, 8 February 2019 at 04:30:23 UTC, Arun > >> > >> Chandrasekaran wrote: > >>> On Friday, 8 February 2019 at 04:13:39 UTC, Sudhi wrote: > [...] > >>> > >>> Works fine for me with DMD64 D Compiler v2.083.1. > >>> https://run.dlang.io/is/RRM8GU > >> > >> My example code was wrong. Below is the right one. > >> > >> struct Company > >> { > >> > >> string name; > >> string location; > >> > >> } > >> > >> struct Racks > >> { > >> > >> int number; > >> int location; > >> > >> } > >> > >> struct Metadata > >> { > >> > >> string name; > >> Company[] companies; > >> Racks[] racks; > >> > >> } > >> > >> struct Item > >> { > >> > >> Metadata[] met; > >> int count; > >> > >> } > >> > >> shared (Item) item; > >> > >> void main() > >> { > >> > >>updateMetadata(); > >> > >> } > >> > >> void updateMetadata() > >> { > >> > >>Company company; > >>company.name = "Hello"; > >>company.location = "Bangalore"; > >>item.met.companies ~= company; > >>import std.stdio: writeln; > >>writeln(item); > >> > >> } > >> > >> https://run.dlang.io/is/iem0PY > > > > You have to cast away shared: > > > > auto loc_item = cast(Item) item; > > loc_item.met ~= m; > > item = cast(shared) loc_item; > > > > Just to be clear, this is not threadsafe and require a mutex if > > you do this other than as init in main. > > You do not need to cast away shared. You had a couple of issues > with your `updateMetadata()` function. > > First of, `met` is an array, so you need to index it: your code > `item.met.companies ~= company` becomes `item.met[0].companies ~= > company`. This will compile, but throw a range error because you > don't have any `Metadata` object in your `met` array. > > I have typed below the revised form of your function > > ``` > void updateMetadata() > { > // create a Company instance. This must be shared > shared Company company; > company.name = "Hello"; > company.location = "Bangalore"; > > // create a shared Metadata instance > shared Metadata m; > m.name = "m"; > > // append m to the array of meta > item.met ~= m; > // append the company to the array of companies, for a given > meta > item.met[0].companies ~= company; > > import std.stdio: writeln; > writeln(item); > } > ``` > > The working version is at https://run.dlang.io/is/RvRKrU > > Cheers, > Edi Honestly, the fact that that code compiles is a bug. You're not supposed to be able to modify shared objects in a manner which isn't guaranteed to be atomic, because it's not thread-safe. The compiler catches it in a number of places, but there are many where it currently doesn't. But regardless of whether the compiler allows such mutation, a mutex (or similar protection mechanism) needs to be used in order to make the code thread-safe. - Jonathan M Davis
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 02:12:29 UTC, Murilo wrote: prints Two likely reasons: the D compiler does compile time stuff at 80 bit, whereas the C++ one probably uses 64 bit, and the D default print rounds more aggressively than default C++ printing. It is useful to put stuff in runtime variables of type `double` to avoid the differnt bit stuff, and print with printf in both languages to ensure that is the same.
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 02:42:09 UTC, Adam D. Ruppe wrote: On Saturday, 9 February 2019 at 02:12:29 UTC, Murilo wrote: prints Two likely reasons: the D compiler does compile time stuff at 80 bit, whereas the C++ one probably uses 64 bit, and the D default print rounds more aggressively than default C++ printing. It is useful to put stuff in runtime variables of type `double` to avoid the differnt bit stuff, and print with printf in both languages to ensure that is the same. Hi, thanks for the information. But I used the type double in D which is supposed to be only 64 bits long and not 80 bits long, the type real is the one which is supposed to be 80 bits long. Right?
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 02:46:52 UTC, Murilo wrote: But I used the type double in D which is supposed to be only 64 bits long and not 80 bits long, the type real is the one which is supposed to be 80 bits long. Right? Right, BUT the compile time stuff is done before that. double a = 1.0 * 2.0; The 1.0*2.0 is done as real inside the compiler, then the *result* is assigned to the 64 bit double. Whereas in a C++ compiler, that would be done 64 bit throughout. So the different intermediate rounding can give a different result. (The `real` thing in D was a massive mistake. It is slow and adds nothing but confusion.)
Re: Handling big FP numbers
On Sat, Feb 09, 2019 at 02:12:29AM +, Murilo via Digitalmars-d-learn wrote: > Why is it that in C when I attribute the number > 991234307654329925.7865 to a double it prints > 991234299470108672. and in D it prints > 9912342990. ? Apparently both languages cause a > certain loss of precision(which is part of converting the decimal > system into the binary system) but why is it that the results are > different? It's not only because of converting decimal to binary, it's also because double only has 64 bits to store information, and your number has far more digits than can possibly fit into 64 bits. Some number of bits are used up for storing the sign and exponent, so `double` really can only store approximately 15 decimal digits. Anything beyond that simply doesn't exist in a `double`, so attempting to print that many digits will inevitably produce garbage trailing digits. If you round the above outputs to about 15 digits, you'll see that they are essentially equal. As to why different output is produced, that's probably just an artifact of different printing algorithms used to output the number. There may be a small amount of difference around or after the 15th digit because D implicitly converts to `real` (which on x86 is the 80-bit proprietary FPU representation) for some operations and rounds it back, while C only operates on 64-bit double. This may cause some slight difference in behaviour around the 15th digit or so. Either way, it is not possible for `double` to hold more than 15 decimal digits, and any output produced from the non-existent digits following that is suspect and probably just random garbage. If you want to hold more than 15 digits, you'll either have to use `real`, which depending on your CPU will be 80-bit (x86) or 128-bit (a few newer, less common CPUs), or an arbitrary-precision library that simulates larger precisions in software, like the MPFR module of libgmp. Note, however, that even even 80-bit real realistically only holds up to about 18 digits, which isn't very much more than a double, and still far too small for your number above. You need at least a 128-bit quadruple precision type (which can represent up to about 34 digits) in order to represent your above number accurately. T -- The fact that anyone still uses AOL shows that even the presence of options doesn't stop some people from picking the pessimal one. - Mike Ellis
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 02:54:18 UTC, Adam D. Ruppe wrote: On Saturday, 9 February 2019 at 02:46:52 UTC, Murilo wrote: But I used the type double in D which is supposed to be only 64 bits long and not 80 bits long, the type real is the one which is supposed to be 80 bits long. Right? Right, BUT the compile time stuff is done before that. double a = 1.0 * 2.0; The 1.0*2.0 is done as real inside the compiler, then the *result* is assigned to the 64 bit double. Whereas in a C++ compiler, that would be done 64 bit throughout. So the different intermediate rounding can give a different result. (The `real` thing in D was a massive mistake. It is slow and adds nothing but confusion.) ahhh okay, thanks for clearing it up. is there a way to bypass that?
Re: Handling big FP numbers
On Sat, Feb 09, 2019 at 02:54:18AM +, Adam D. Ruppe via Digitalmars-d-learn wrote: [...] > (The `real` thing in D was a massive mistake. It is slow and adds > nothing but confusion.) Yeah, it is also the only variable-width built-in type in D, which makes it a wart in an otherwise elegant system of fixed-width types. And 80-bit extended precision is non-standard and non-conformant to IEEE 754, and who other than Intel engineers can tell how it behaves in corner cases? It also causes std.math to make a laughing stock of D, because the majority of math functions implicitly convert to real and cast the result back to the source type, thus representing a hidden performance cost even if the caller explicitly used float precisely to reduce the cost of computing at a higher precision. And it prevents the optimizer from, e.g., taking advantage of SSE instructions for faster computation with float/double. T -- If lightning were to ever strike an orchestra, it'd always hit the conductor first.
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 03:03:41 UTC, H. S. Teoh wrote: It's not only because of converting decimal to binary, it's also because double only has 64 bits to store information, and your number has far more digits than can possibly fit into 64 bits. Adding to that, here's a nice little online calculator that will show the binary representation of a given decimal number: https://www.h-schmidt.net/FloatConverter/IEEE754.html
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 03:03:41 UTC, H. S. Teoh wrote: On Sat, Feb 09, 2019 at 02:12:29AM +, Murilo via Digitalmars-d-learn wrote: Why is it that in C when I attribute the number 991234307654329925.7865 to a double it prints 991234299470108672. and in D it prints 9912342990. ? Apparently both languages cause a certain loss of precision(which is part of converting the decimal system into the binary system) but why is it that the results are different? It's not only because of converting decimal to binary, it's also because double only has 64 bits to store information, and your number has far more digits than can possibly fit into 64 bits. Some number of bits are used up for storing the sign and exponent, so `double` really can only store approximately 15 decimal digits. Anything beyond that simply doesn't exist in a `double`, so attempting to print that many digits will inevitably produce garbage trailing digits. If you round the above outputs to about 15 digits, you'll see that they are essentially equal. As to why different output is produced, that's probably just an artifact of different printing algorithms used to output the number. There may be a small amount of difference around or after the 15th digit because D implicitly converts to `real` (which on x86 is the 80-bit proprietary FPU representation) for some operations and rounds it back, while C only operates on 64-bit double. This may cause some slight difference in behaviour around the 15th digit or so. Now, changing a little bit the subject. All FPs in D turn out to be printed differently than they are in C and in C it comes out a little more precise than in D. Is this really supposed to happen?
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 03:21:51 UTC, Murilo wrote: Now, changing a little bit the subject. All FPs in D turn out to be printed differently than they are in C and in C it comes out a little more precise than in D. Is this really supposed to happen? Like I said in my first message, the D default rounds off more than the C default. This usually results in more readable stuff - the extra noise at the end is not that helpful in most cases. But you can change this with the format specifiers (use `writefln` instead of `writeln` and give a precision argument) or, of course, you can use the same C printf function from D.
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 03:28:24 UTC, Adam D. Ruppe wrote: On Saturday, 9 February 2019 at 03:21:51 UTC, Murilo wrote: Now, changing a little bit the subject. All FPs in D turn out to be printed differently than they are in C and in C it comes out a little more precise than in D. Is this really supposed to happen? Like I said in my first message, the D default rounds off more than the C default. This usually results in more readable stuff - the extra noise at the end is not that helpful in most cases. But you can change this with the format specifiers (use `writefln` instead of `writeln` and give a precision argument) or, of course, you can use the same C printf function from D. Thanks but here is the situation, I use printf("%.20f", 0.1); in both C and D, C returns 0.1555 whereas D returns 0.10001000. So I understand your point, D rounds off more, but that causes loss of precision, isn't that something bad if you are working with math and physics for example?
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 03:28:24 UTC, Adam D. Ruppe wrote: On Saturday, 9 February 2019 at 03:21:51 UTC, Murilo wrote: Now, changing a little bit the subject. All FPs in D turn out to be printed differently than they are in C and in C it comes out a little more precise than in D. Is this really supposed to happen? Like I said in my first message, the D default rounds off more than the C default. This usually results in more readable stuff - the extra noise at the end is not that helpful in most cases. But you can change this with the format specifiers (use `writefln` instead of `writeln` and give a precision argument) or, of course, you can use the same C printf function from D. Thanks, but which precision specifier should I use? I already tried "%.20f" but it still produces a result different from C? Is there a way to make it identical to C?
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 03:33:13 UTC, Murilo wrote: Thanks but here is the situation, I use printf("%.20f", 0.1); in both C and D, C returns 0.1555 whereas D returns 0.10001000. So I understand your point, D rounds off more, but that causes loss of precision, isn't that something bad if you are working with math and physics for example? 0.1 in floating point is actually 0.10001490116119384765625 behind the scenes. So why is it important that it displays as: 0.1555 versus 0.10001000 ? *Technically* the D version has less error, relative to the internal binary representation. Since there's no exact way of representing 0.1 in floating point, the computer has no way of knowing you really mean "0.1 decimal". If the accuracy is that important to you, you'll probably have to look into software-only number representations, for arbitrary decimal precision (I've not explored them in D, but other languages have things like "BigDecimal" data types)
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 04:30:22 UTC, DanielG wrote: On Saturday, 9 February 2019 at 03:33:13 UTC, Murilo wrote: Thanks but here is the situation, I use printf("%.20f", 0.1); in both C and D, C returns 0.1555 whereas D returns 0.10001000. So I understand your point, D rounds off more, but that causes loss of precision, isn't that something bad if you are working with math and physics for example? 0.1 in floating point is actually 0.10001490116119384765625 behind the scenes. So why is it important that it displays as: 0.1555 versus 0.10001000 ? *Technically* the D version has less error, relative to the internal binary representation. Since there's no exact way of representing 0.1 in floating point, the computer has no way of knowing you really mean "0.1 decimal". If the accuracy is that important to you, you'll probably have to look into software-only number representations, for arbitrary decimal precision (I've not explored them in D, but other languages have things like "BigDecimal" data types) Thank you very much for clearing this up. But how do I make D behave just like C? Is there a way to do that?
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 04:32:44 UTC, Murilo wrote: Thank you very much for clearing this up. But how do I make D behave just like C? Is there a way to do that? Off the top of my head, you'd have to link against libc so you could use printf() directly. But may I ask why that is so important to you?
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 04:36:26 UTC, DanielG wrote: On Saturday, 9 February 2019 at 04:32:44 UTC, Murilo wrote: Thank you very much for clearing this up. But how do I make D behave just like C? Is there a way to do that? Off the top of my head, you'd have to link against libc so you could use printf() directly. But may I ask why that is so important to you? That is important because there are some websites with problems for you to send them your code and it automatically checks if you got it right, in D it will always say "Wrong Answer" cause it outputs a different string than what is expected.
Re: Handling big FP numbers
On Sat, Feb 09, 2019 at 03:52:38AM +, Murilo via Digitalmars-d-learn wrote: > On Saturday, 9 February 2019 at 03:28:24 UTC, Adam D. Ruppe wrote: [...] > > But you can change this with the format specifiers (use `writefln` > > instead of `writeln` and give a precision argument) or, of course, > > you can use the same C printf function from D. > > Thanks, but which precision specifier should I use? I already tried > "%.20f" but it still produces a result different from C? Is there a > way to make it identical to C? I say again, you're asking for far more digits than are actually there. The extra digits are only an illusion of accuracy; they are essentially garbage values that have no real meaning. It really does not make any sense to print more digits than are actually there. On the other hand, if your purpose is to export the double in a textual representation that guarantees reproduction of exactly the same bits when imported later, you could use the %a format which writes out the mantissa in exact hexadecimal form. It can then be parsed again later to reproduce the same bits as was in the original double. Or if your goal is simply to replicate C behaviour, there's also the option of calling the C fprintf directly. Just import core.stdc.stdio or declare the prototype yourself in an extern(C) declaration. T -- If it breaks, you get to keep both pieces. -- Software disclaimer notice
Re: Handling big FP numbers
On Sat, Feb 09, 2019 at 04:36:26AM +, DanielG via Digitalmars-d-learn wrote: > On Saturday, 9 February 2019 at 04:32:44 UTC, Murilo wrote: > > Thank you very much for clearing this up. But how do I make D > > behave just like C? Is there a way to do that? > > Off the top of my head, you'd have to link against libc so you could > use printf() directly. There's no need to do that, D programs already link to libc by default. All you need is to declare the right extern(C) prototype (or just import core.stdc.*) and you can call the function just like in C. With the caveat, of course, that D strings are not the same as C's char*, so you have to use .ptr for string literals and toStringz for dynamic strings. T -- People tell me I'm stubborn, but I refuse to accept it!
Re: Handling big FP numbers
On Saturday, 9 February 2019 at 02:12:29 UTC, Murilo wrote: Why is it that in C when I attribute the number 991234307654329925.7865 to a double it prints 991234299470108672. and in D it prints 9912342990. ? Apparently both languages cause a certain loss of precision(which is part of converting the decimal system into the binary system) but why is it that the results are different? Do you want to learn D programming then check http://letsfindcourse.com/d-programming-courses Here you will find the best D programming tutorials recommended by programming community.