Re: Runtime error in code on main page
On Tuesday, 25 August 2015 at 01:27:37 UTC, Adrian wrote: The "Get your local weather report" sample code on the main page generates the following error: /d683/f748.d(32): Error: undefined identifier centerJustifier Someone might want to address that. I also get an error when I hit "Run" for the "D is like ..." program. Error message: Unable to fork: Cannot allocate memory
Re: std.data.json formal review
On 08/18/2015 12:21 AM, Andrei Alexandrescu wrote: > * All new stuff should go in std.experimental. I assume "stdx" would > change to that, should this work be merged. Though stdx (or better std.x) would have been a prettier and more exciting name for std.experimental to begin with.
Re: std.data.json formal review
On Saturday, 22 August 2015 at 13:41:49 UTC, Sönke Ludwig wrote: There is more than the actual call to validate(), such as writing tests and making sure the surroundings work, adjusting the interface and writing documentation. It's not *that* much work, but nonetheless wasted work. I also still think that this hasn't been a bad idea at all. Because it speeds up the most important use case, parsing JSON from a non-memory source that has not yet been validated. I also very much like the idea of making it a programming error to have invalid UTF stored in a string, i.e. forcing the validation to happen before the cast from bytes to chars. Also see "utf/unicode should only be validated once" https://issues.dlang.org/show_bug.cgi?id=14919 If combining lexing and validation is faster (why?) then a ubyte consuming interface should be available, though why couldn't it be done by adding a lazy ubyte->char validator range to std.utf. In any case during lexing we should avoid autodecoding of narrow strings for redundant validation.
Re: Sub forum for dmd implementation details
On Monday, 24 August 2015 at 17:00:31 UTC, Benjamin Thaut wrote: As a occasional contributor to dmd I usually manage to get everything working the way I want by digging through the dmd source code long enough, but sometimes bad / non-existing documentation and missing knowdelge result in suboptimal solutions or unsolved problems. I would greatly appreciate a subforum which purpose it is to discuss compiler implementation details. I know that there is dmd-internals, but it seems that this forum only gets spammed by some bot with pull-request messages. I'm in the same boat. The Github events have a high noise-to-information ratio, and given that Github already has a way to subscribe to a repository's events, they seem redundant. Mike
Re: How many bytes in a real ?
On 25-Aug-2015 01:29, Guillaume Chatelet wrote: On Monday, 24 August 2015 at 22:08:03 UTC, Guillaume Chatelet wrote: On Monday, 24 August 2015 at 21:58:48 UTC, rsw0x wrote: On Monday, 24 August 2015 at 21:55:40 UTC, Guillaume Chatelet wrote: On linux x86_64 : real.sizeof == 16 but it looks like only the first the first 10 bytes are used (ie. 80bits) Is there a way to know the real size of a real ? http://dlang.org/type.html largest FP size implemented in hardwareImplementation Note: 80 bits for x86 CPUs or double size, whichever is larger Yep I found this, I'd like to know this information at compile time. I actually found another way(1) but if someone knows how to get this information at compile time I'm still interested. Thx ! 1. https://github.com/D-Programming-Language/dmd/pull/4952 real.sizeof ? -- Dmitry Olshansky
Re: How many bytes in a real ?
On 25-Aug-2015 08:28, Dmitry Olshansky wrote: On 25-Aug-2015 01:29, Guillaume Chatelet wrote: On Monday, 24 August 2015 at 22:08:03 UTC, Guillaume Chatelet wrote: On Monday, 24 August 2015 at 21:58:48 UTC, rsw0x wrote: On Monday, 24 August 2015 at 21:55:40 UTC, Guillaume Chatelet wrote: On linux x86_64 : real.sizeof == 16 but it looks like only the first the first 10 bytes are used (ie. 80bits) Is there a way to know the real size of a real ? http://dlang.org/type.html largest FP size implemented in hardwareImplementation Note: 80 bits for x86 CPUs or double size, whichever is larger Yep I found this, I'd like to know this information at compile time. I actually found another way(1) but if someone knows how to get this information at compile time I'm still interested. Thx ! 1. https://github.com/D-Programming-Language/dmd/pull/4952 real.sizeof ? NVM -- Dmitry Olshansky
Re: Runtime error in code on main page
On Mon, Aug 24, 2015 at 08:01:12PM -0700, H. S. Teoh via Digitalmars-d wrote: > On Tue, Aug 25, 2015 at 02:34:11AM +, rsw0x via Digitalmars-d wrote: > > On Tuesday, 25 August 2015 at 02:24:32 UTC, H. S. Teoh wrote: > > >On Tue, Aug 25, 2015 at 01:27:36AM +, Adrian via Digitalmars-d wrote: > > >>The "Get your local weather report" sample code on the main page > > >>generates the following error: > > >> > > >>/d683/f748.d(32): Error: undefined identifier centerJustifier > > >> > > >>Someone might want to address that. > > > > > >It works on the latest git HEAD. Which version of the compiler are > > >you using? That example probably should be reworked to work with > > >earlier compilers. :-) > > > > > > > > >T > > > > He means the example that you can run in-browser. > > He's right, it fails. > > It works on git HEAD. > > But apparently not on older compilers. [...] Apparently it works on dmd-2.068.0 as well, but not on dmd-2.066.1. Not sure exactly where it started working, but it should be revised to work on older compilers. T -- Long, long ago, the ancient Chinese invented a device that lets them see through walls. It was called the "window".
Re: Runtime error in code on main page
On Tue, Aug 25, 2015 at 02:34:11AM +, rsw0x via Digitalmars-d wrote: > On Tuesday, 25 August 2015 at 02:24:32 UTC, H. S. Teoh wrote: > >On Tue, Aug 25, 2015 at 01:27:36AM +, Adrian via Digitalmars-d wrote: > >>The "Get your local weather report" sample code on the main page > >>generates the following error: > >> > >>/d683/f748.d(32): Error: undefined identifier centerJustifier > >> > >>Someone might want to address that. > > > >It works on the latest git HEAD. Which version of the compiler are > >you using? That example probably should be reworked to work with > >earlier compilers. :-) > > > > > >T > > He means the example that you can run in-browser. > He's right, it fails. It works on git HEAD. But apparently not on older compilers. T -- Never wrestle a pig. You both get covered in mud, and the pig likes it.
Re: Runtime error in code on main page
On Tuesday, 25 August 2015 at 02:24:32 UTC, H. S. Teoh wrote: On Tue, Aug 25, 2015 at 01:27:36AM +, Adrian via Digitalmars-d wrote: The "Get your local weather report" sample code on the main page generates the following error: /d683/f748.d(32): Error: undefined identifier centerJustifier Someone might want to address that. It works on the latest git HEAD. Which version of the compiler are you using? That example probably should be reworked to work with earlier compilers. :-) T He means the example that you can run in-browser. He's right, it fails.
Re: Runtime error in code on main page
On Tue, Aug 25, 2015 at 01:27:36AM +, Adrian via Digitalmars-d wrote: > The "Get your local weather report" sample code on the main page > generates the following error: > > /d683/f748.d(32): Error: undefined identifier centerJustifier > > Someone might want to address that. It works on the latest git HEAD. Which version of the compiler are you using? That example probably should be reworked to work with earlier compilers. :-) T -- I don't trust computers, I've spent too long programming to think that they can get anything right. -- James Miller
Re: Casting double to ulong weirdness
On Monday, 24 August 2015 at 16:52:54 UTC, Márcio Martins wrote: I'm posting this here for visibility. This was silently corrupting our data, and might be doing the same for others as well. import std.stdio; void main() { double x = 1.2; writeln(cast(ulong)(x * 10.0)); double y = 1.2 * 10.0; writeln(cast(ulong)y); } Output: 11 12 to!ulong instead of the cast does the right thing, and is a viable work-around. Issue: https://issues.dlang.org/show_bug.cgi?id=14958) http://www.smbc-comics.com/?id=2999
Runtime error in code on main page
The "Get your local weather report" sample code on the main page generates the following error: /d683/f748.d(32): Error: undefined identifier centerJustifier Someone might want to address that.
Re: Casting double to ulong weirdness
On Monday, 24 August 2015 at 21:34:23 UTC, Márcio Martins wrote: Whatever the issue is, it is not unavoidable, because as has been shown, other languages do it correctly. There's no guarantee that it will be done consistently or correctly in C or C++ to my knowledge. Some compilers will do it consistently, but it's absolutely not portable. It is an issue of precision. In order to change from real to double, some bits must be lost. Since certain numbers cannot be represented, the CPU must round or truncate. There is no mention of real anywhere in any code. The intent is clearly stated in the code and while I accept precision and rounding errors, especially because DMD has no way to select a floating point model, that I am aware of, at least, it's very hard for me to accept the inconsistency. It's fully consistent with what DMD claims to do: http://dlang.org/portability.html While a compiler can guarantee consistency, I don't know of any way to guarantee correctness, which makes the question of consistency irrelevant. There's no way to know what will happen when you run the program. What is the correct way to truncate, not round, a floating-point value to an integer? If you can be an epsilon above or below the exact answer, there's no way to guarantee correctness unless you know you're not doing something that resembles integer operations. If the exact answer is 12.2 or 12.6, you can do it correctly. If it is 12.0 or 23.0, you can get the wrong answer.
Re: How many bytes in a real ?
On Monday, 24 August 2015 at 21:55:40 UTC, Guillaume Chatelet wrote: On linux x86_64 : real.sizeof == 16 but it looks like only the first the first 10 bytes are used (ie. 80bits) Is there a way to know the real size of a real ? The best I can think of is to use the mant_dig property which returns the number of bits in the mantissa. http://dpaste.dzfl.pl/9889b3d0bd5b
Re: Casting double to ulong weirdness
On Monday, 24 August 2015 at 22:12:42 UTC, H. S. Teoh wrote: On Mon, Aug 24, 2015 at 09:34:22PM +, via Digitalmars-d wrote: [...] What is the correct way to truncate, not round, a floating-point value to an integer? std.math.trunc. T import std.stdio; import std.math; void main() { double x = 1.2; writeln(std.math.trunc(x * 10.0)); double y = x * 10.0; writeln(std.math.trunc(y)); } Outputs: 11 12
Re: How many bytes in a real ?
On Monday, 24 August 2015 at 22:08:03 UTC, Guillaume Chatelet wrote: On Monday, 24 August 2015 at 21:58:48 UTC, rsw0x wrote: On Monday, 24 August 2015 at 21:55:40 UTC, Guillaume Chatelet wrote: On linux x86_64 : real.sizeof == 16 but it looks like only the first the first 10 bytes are used (ie. 80bits) Is there a way to know the real size of a real ? http://dlang.org/type.html largest FP size implemented in hardwareImplementation Note: 80 bits for x86 CPUs or double size, whichever is larger Yep I found this, I'd like to know this information at compile time. Oh, my apologies. I've looked around and I can't seem to find anything. Sorry for the noise.
Re: How many bytes in a real ?
On Monday, 24 August 2015 at 22:08:03 UTC, Guillaume Chatelet wrote: On Monday, 24 August 2015 at 21:58:48 UTC, rsw0x wrote: On Monday, 24 August 2015 at 21:55:40 UTC, Guillaume Chatelet wrote: On linux x86_64 : real.sizeof == 16 but it looks like only the first the first 10 bytes are used (ie. 80bits) Is there a way to know the real size of a real ? http://dlang.org/type.html largest FP size implemented in hardwareImplementation Note: 80 bits for x86 CPUs or double size, whichever is larger Yep I found this, I'd like to know this information at compile time. I actually found another way(1) but if someone knows how to get this information at compile time I'm still interested. Thx ! 1. https://github.com/D-Programming-Language/dmd/pull/4952
Re: Casting double to ulong weirdness
On Mon, Aug 24, 2015 at 09:34:22PM +, via Digitalmars-d wrote: [...] > What is the correct way to truncate, not round, a floating-point value > to an integer? std.math.trunc. T -- Having a smoking section in a restaurant is like having a peeing section in a swimming pool. -- Edward Burr
Re: How many bytes in a real ?
On Monday, 24 August 2015 at 21:58:48 UTC, rsw0x wrote: On Monday, 24 August 2015 at 21:55:40 UTC, Guillaume Chatelet wrote: On linux x86_64 : real.sizeof == 16 but it looks like only the first the first 10 bytes are used (ie. 80bits) Is there a way to know the real size of a real ? http://dlang.org/type.html largest FP size implemented in hardwareImplementation Note: 80 bits for x86 CPUs or double size, whichever is larger Yep I found this, I'd like to know this information at compile time.
Re: How many bytes in a real ?
On Monday, 24 August 2015 at 21:55:40 UTC, Guillaume Chatelet wrote: On linux x86_64 : real.sizeof == 16 but it looks like only the first the first 10 bytes are used (ie. 80bits) Is there a way to know the real size of a real ? http://dlang.org/type.html largest FP size implemented in hardwareImplementation Note: 80 bits for x86 CPUs or double size, whichever is larger
How many bytes in a real ?
On linux x86_64 : real.sizeof == 16 but it looks like only the first the first 10 bytes are used (ie. 80bits) Is there a way to know the real size of a real ?
Re: Casting double to ulong weirdness
On Monday, 24 August 2015 at 21:03:50 UTC, Steven Schveighoffer wrote: On 8/24/15 4:34 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" \"" wrote: On Monday, 24 August 2015 at 19:23:44 UTC, Steven Schveighoffer wrote: On 8/24/15 1:43 PM, bachmeier wrote: On Monday, 24 August 2015 at 16:52:54 UTC, Márcio Martins wrote: I'm posting this here for visibility. This was silently corrupting our data, and might be doing the same for others as well. import std.stdio; void main() { double x = 1.2; writeln(cast(ulong)(x * 10.0)); double y = 1.2 * 10.0; writeln(cast(ulong)y); } Output: 11 12 to!ulong instead of the cast does the right thing, and is a viable work-around. Issue: https://issues.dlang.org/show_bug.cgi?id=14958) I would not describe to!ulong as a "work-around". You just discovered one of the reasons to! exists: it is the right way to do it and cast(ulong) is the wrong way. As the others have noted, floating point is tricky business, and you need to use the right tools for the job. real y = x * 10.0; writeln(y.to!ulong); // 11 to! does not do anything different than cast. What is happening here is the implicit cast from real to double. D treats the result of x * 10.0 as type double, but it's done at real precision. In that conversion, the error is hidden by a rounding automatically done by the processor I think. Whatever the issue is, it is not unavoidable, because as has been shown, other languages do it correctly. Your other examples use doubles, not reals. It's not apples to apples. All my examples are doubles, and I have tested them all in C++ as well, using doubles. It is indeed apples to apples :) From the data presented so far, it seems like the issue is that the mul is performed in 80-bit precision, storing it before the cast forces a truncation down to 64-bit. Not just truncation, rounding too. What? If rounding was performed, then it would work as expected. i.e. both outputs would be 12. Similarly, passing it to a function will also truncate to 64-bit, due to ABIs. This is why to! works as expected. Please do keep in mind that the issue is not one of precision, but one of inconsistency. It is an issue of precision. In order to change from real to double, some bits must be lost. Since certain numbers cannot be represented, the CPU must round or truncate. There is no mention of real anywhere in any code. The intent is clearly stated in the code and while I accept precision and rounding errors, especially because DMD has no way to select a floating point model, that I am aware of, at least, it's very hard for me to accept the inconsistency. They are not the same thing. The result being 11 or 12 is irrelevant to this issue. It should just be the same for two instances of the same expression. They are not the same expression. One goes from double through multiplication to real, then back to double, then to ulong. The other skips the real to double conversion and goes directly to ulong. There is only 1 floating-point operation and one cast per expression. They are effectively the same except one value is stored in a temporary before casting. The intent expressed in the code is absolutely the same. All values are the same, operation order is the same, and types are all the same. The real issue here is that you are not correctly converting from a floating point number to an integer. In an attempt to make things more obvious, consider this example, which also illustrates why to! works, despite apparently doing nothing extra at all. double noop(double z) { return z; } void main() { double x = 1.2; writeln(cast(ulong)(x * 10.0)); writeln(cast(ulong)noop(x * 10.0)); } Outputs: 11 12 I understand the inconsistency, and I agree it is an issue that should be examined. But the issue is entirely avoidable by not using incorrect methods to convert from floating point to integer after floating point operations introduce some small level of error. Perhaps there is some way to make it properly round in this case, but I guarantee it will not fix all floating point errors. -Steve What is the correct way to truncate, not round, a floating-point value to an integer?
Re: Casting double to ulong weirdness
On 8/24/15 5:03 PM, Steven Schveighoffer wrote: Whatever the issue is, it is not unavoidable, because as has been shown, other languages do it correctly. Your other examples use doubles, not reals. It's not apples to apples. #include int main() { long double x = 1.2; x *= 10.0; printf("%lld\n", (unsigned long long)x); } output: 11 -Steve
Re: Casting double to ulong weirdness
On 8/24/15 4:34 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" \"" wrote: On Monday, 24 August 2015 at 19:23:44 UTC, Steven Schveighoffer wrote: On 8/24/15 1:43 PM, bachmeier wrote: On Monday, 24 August 2015 at 16:52:54 UTC, Márcio Martins wrote: I'm posting this here for visibility. This was silently corrupting our data, and might be doing the same for others as well. import std.stdio; void main() { double x = 1.2; writeln(cast(ulong)(x * 10.0)); double y = 1.2 * 10.0; writeln(cast(ulong)y); } Output: 11 12 to!ulong instead of the cast does the right thing, and is a viable work-around. Issue: https://issues.dlang.org/show_bug.cgi?id=14958) I would not describe to!ulong as a "work-around". You just discovered one of the reasons to! exists: it is the right way to do it and cast(ulong) is the wrong way. As the others have noted, floating point is tricky business, and you need to use the right tools for the job. real y = x * 10.0; writeln(y.to!ulong); // 11 to! does not do anything different than cast. What is happening here is the implicit cast from real to double. D treats the result of x * 10.0 as type double, but it's done at real precision. In that conversion, the error is hidden by a rounding automatically done by the processor I think. Whatever the issue is, it is not unavoidable, because as has been shown, other languages do it correctly. Your other examples use doubles, not reals. It's not apples to apples. From the data presented so far, it seems like the issue is that the mul is performed in 80-bit precision, storing it before the cast forces a truncation down to 64-bit. Not just truncation, rounding too. Similarly, passing it to a function will also truncate to 64-bit, due to ABIs. This is why to! works as expected. Please do keep in mind that the issue is not one of precision, but one of inconsistency. It is an issue of precision. In order to change from real to double, some bits must be lost. Since certain numbers cannot be represented, the CPU must round or truncate. They are not the same thing. The result being 11 or 12 is irrelevant to this issue. It should just be the same for two instances of the same expression. They are not the same expression. One goes from double through multiplication to real, then back to double, then to ulong. The other skips the real to double conversion and goes directly to ulong. The real issue here is that you are not correctly converting from a floating point number to an integer. In an attempt to make things more obvious, consider this example, which also illustrates why to! works, despite apparently doing nothing extra at all. double noop(double z) { return z; } void main() { double x = 1.2; writeln(cast(ulong)(x * 10.0)); writeln(cast(ulong)noop(x * 10.0)); } Outputs: 11 12 I understand the inconsistency, and I agree it is an issue that should be examined. But the issue is entirely avoidable by not using incorrect methods to convert from floating point to integer after floating point operations introduce some small level of error. Perhaps there is some way to make it properly round in this case, but I guarantee it will not fix all floating point errors. -Steve
Re: Casting double to ulong weirdness
On Monday, 24 August 2015 at 19:23:44 UTC, Steven Schveighoffer wrote: On 8/24/15 1:43 PM, bachmeier wrote: On Monday, 24 August 2015 at 16:52:54 UTC, Márcio Martins wrote: I'm posting this here for visibility. This was silently corrupting our data, and might be doing the same for others as well. import std.stdio; void main() { double x = 1.2; writeln(cast(ulong)(x * 10.0)); double y = 1.2 * 10.0; writeln(cast(ulong)y); } Output: 11 12 to!ulong instead of the cast does the right thing, and is a viable work-around. Issue: https://issues.dlang.org/show_bug.cgi?id=14958) I would not describe to!ulong as a "work-around". You just discovered one of the reasons to! exists: it is the right way to do it and cast(ulong) is the wrong way. As the others have noted, floating point is tricky business, and you need to use the right tools for the job. real y = x * 10.0; writeln(y.to!ulong); // 11 to! does not do anything different than cast. What is happening here is the implicit cast from real to double. D treats the result of x * 10.0 as type double, but it's done at real precision. In that conversion, the error is hidden by a rounding automatically done by the processor I think. -Steve Whatever the issue is, it is not unavoidable, because as has been shown, other languages do it correctly. From the data presented so far, it seems like the issue is that the mul is performed in 80-bit precision, storing it before the cast forces a truncation down to 64-bit. Similarly, passing it to a function will also truncate to 64-bit, due to ABIs. This is why to! works as expected. Please do keep in mind that the issue is not one of precision, but one of inconsistency. They are not the same thing. The result being 11 or 12 is irrelevant to this issue. It should just be the same for two instances of the same expression. In an attempt to make things more obvious, consider this example, which also illustrates why to! works, despite apparently doing nothing extra at all. double noop(double z) { return z; } void main() { double x = 1.2; writeln(cast(ulong)(x * 10.0)); writeln(cast(ulong)noop(x * 10.0)); } Outputs: 11 12
Re: std.data.json formal review
On 8/22/2015 5:21 AM, Sönke Ludwig wrote: Am 17.08.2015 um 00:03 schrieb Walter Bright: D is going to be built around ranges as a fundamental way of coding. Users will need to learn something about them. Appending .array is not a big hill to climb. It isn't if you get taught about it. But it surely is if you don't know about it yet and try to get something working based only on the JSON API (language newcomer that wants to work with JSON). Not if the illuminating example in the Json API description does it that way. Newbies will tend to copy/pasta the examples as a starting point. It's also still an additional thing to remember, type and read, making it an additional piece of cognitive load, even for developers that are fluent with this. Have many of such pieces and they add up to a point where productivity goes to its knees. Having composable components behaving in predictable ways is not an additional piece of cognitive load, it is less of one. I already personally find it quite annoying constantly having to import std.range, std.array and std.algorithm to just use some small piece of functionality in std.algorithm. It's also often not clear in which of the three modules/packages a certain function is. We need to find a better balance here if D is to keep its appeal as a language where you stay in "the zone" (a.k.a flow), which always has been a big thing for me. If I buy a toy car, I get a toy car. If I get a lego set, I can build any toy with it. I believe the composable component approach will make Phobos smaller and much more flexible and useful, as opposed to monolithic APIs.
Re: Casting double to ulong weirdness
On Monday, 24 August 2015 at 19:23:44 UTC, Steven Schveighoffer wrote: real y = x * 10.0; writeln(y.to!ulong); // 11 to! does not do anything different than cast. What is happening here is the implicit cast from real to double. D treats the result of x * 10.0 as type double, but it's done at real precision. In that conversion, the error is hidden by a rounding automatically done by the processor I think. -Steve Yes, I was mistaken. You have to use roundTo or std.math.round. to! and cast both truncate.
Destructors, deallocateAll, and GCAllocator
I've discovered that several allocators in std.experimental.allocator call deallocateAll on their parent allocators during their destructors. This is not a problem unless the parent allocator happens to be GCAllocator and the original destructor call was caused by a GC collection. GC.free cannot be called while the GC is active. (The resulting InvalidMemoryOperationError is why DCD 0.7.0 final isn't out today) Any ideas how this problem should be solved?
Re: Casting double to ulong weirdness
On 8/24/15 1:43 PM, bachmeier wrote: On Monday, 24 August 2015 at 16:52:54 UTC, Márcio Martins wrote: I'm posting this here for visibility. This was silently corrupting our data, and might be doing the same for others as well. import std.stdio; void main() { double x = 1.2; writeln(cast(ulong)(x * 10.0)); double y = 1.2 * 10.0; writeln(cast(ulong)y); } Output: 11 12 to!ulong instead of the cast does the right thing, and is a viable work-around. Issue: https://issues.dlang.org/show_bug.cgi?id=14958) I would not describe to!ulong as a "work-around". You just discovered one of the reasons to! exists: it is the right way to do it and cast(ulong) is the wrong way. As the others have noted, floating point is tricky business, and you need to use the right tools for the job. real y = x * 10.0; writeln(y.to!ulong); // 11 to! does not do anything different than cast. What is happening here is the implicit cast from real to double. D treats the result of x * 10.0 as type double, but it's done at real precision. In that conversion, the error is hidden by a rounding automatically done by the processor I think. -Steve
Re: Casting double to ulong weirdness
On 8/24/15 3:15 PM, bachmeier wrote: On Monday, 24 August 2015 at 18:59:58 UTC, Steven Schveighoffer wrote: All this gets down to: FP cannot accurately represent decimal. Should this be fixed? Can it be fixed? I don't know. But I would be very cautious about converting anything FP to integers without some epsilon. -Steve I don't see anything that needs to be fixed, because I don't think anything is broken - there is nothing that violates my understanding of floating point precision in D. cast is not round. What is broken is a program that attempts to convert a double to an integer type using a cast rather than the functions that were written to do it correctly. What is surprising, and possibly buggy, is that none of these operations involve real, but the issue only happens because under the hood, real is used instead of double for the multiplication. I pretty much agree with you that the code is written incorrectly. But it is unfortunate it differs in the way it handles this from C. I think this issue has been brought up before on the newsgroup, especially where CTFE is involved. -Steve
Re: Casting double to ulong weirdness
On Mon, Aug 24, 2015 at 07:15:43PM +, bachmeier via Digitalmars-d wrote: > On Monday, 24 August 2015 at 18:59:58 UTC, Steven Schveighoffer wrote: > >All this gets down to: FP cannot accurately represent decimal. Should > >this be fixed? Can it be fixed? I don't know. But I would be very > >cautious about converting anything FP to integers without some > >epsilon. > > > >-Steve > > I don't see anything that needs to be fixed, because I don't think > anything is broken - there is nothing that violates my understanding > of floating point precision in D. > > cast is not round. What is broken is a program that attempts to > convert a double to an integer type using a cast rather than the > functions that were written to do it correctly. +1. Floating-point != mathematical real numbers. Don't expect it to behave the same. T -- It's amazing how careful choice of punctuation can leave you hanging:
Re: Casting double to ulong weirdness
On Monday, 24 August 2015 at 18:59:58 UTC, Steven Schveighoffer wrote: All this gets down to: FP cannot accurately represent decimal. Should this be fixed? Can it be fixed? I don't know. But I would be very cautious about converting anything FP to integers without some epsilon. -Steve I don't see anything that needs to be fixed, because I don't think anything is broken - there is nothing that violates my understanding of floating point precision in D. cast is not round. What is broken is a program that attempts to convert a double to an integer type using a cast rather than the functions that were written to do it correctly.
Re: Casting double to ulong weirdness
On 8/24/15 2:38 PM, Steven Schveighoffer wrote: On 8/24/15 2:06 PM, rumbu wrote: BTW, 1.2 and 12.0 are directly representable as double In C++: printf("%.20f\r\n", 1.2); printf("%.20f\r\n", 12.0); will output: 1.2000 12. Either upcasting to real is the wrong decision here, either the writeln string conversion is wrong. I don't think they are directly representable as floating point, because they are have factors other than 2 in the decimal portion. From my understanding, anything that only has to do with powers of 2 are representable in floating point, just like you cannot represent 1/3 in decimal exactly. But there is definitely something weird going on with the casting. I wrote this program: testfp.d: extern(C) void foo(double x); void main() { double x = 1.2; foo(x); } testfp2.d: extern(C) void foo(double x) { import std.stdio; writeln(cast(ulong)(x * 10.0)); } testfp2.c: #include void foo(double x) { printf("%lld\n", (unsigned long long)(x * 10)); } If I link testfp.d against testfp2.c, then it outputs 12. If I link against testfp2.d, it outputs 11. More data: It definitely has something to do with the representation of 1.2 * 10.0 in *real*. I changed the code so that it writes the result of the multiplication to a shared double. In this case it *works* and prints 12, just like C does. This also works: double x = 1.2; double y = x * 10.0; writeln(cast(ulong)y); // 12 However, change y to a real, and you get 11. Note that if I first convert from real to double, then convert to ulong, it works. This code: double x = 1.2; double x2 = x * 10.0; real y = x * 10.0; real y2 = x2; double y3 = y; writefln("%a, %a, %a", y, y2, cast(real)y3); outputs: 0xb.ep+0, 0xcp+0, 0xcp+0 So some rounding happens in the conversion from real to double, that doesn't happen in the conversion from real to ulong. All this gets down to: FP cannot accurately represent decimal. Should this be fixed? Can it be fixed? I don't know. But I would be very cautious about converting anything FP to integers without some epsilon. -Steve
Re: Casting double to ulong weirdness
On 8/24/15 2:06 PM, rumbu wrote: BTW, 1.2 and 12.0 are directly representable as double In C++: printf("%.20f\r\n", 1.2); printf("%.20f\r\n", 12.0); will output: 1.2000 12. Either upcasting to real is the wrong decision here, either the writeln string conversion is wrong. I don't think they are directly representable as floating point, because they are have factors other than 2 in the decimal portion. From my understanding, anything that only has to do with powers of 2 are representable in floating point, just like you cannot represent 1/3 in decimal exactly. But there is definitely something weird going on with the casting. I wrote this program: testfp.d: extern(C) void foo(double x); void main() { double x = 1.2; foo(x); } testfp2.d: extern(C) void foo(double x) { import std.stdio; writeln(cast(ulong)(x * 10.0)); } testfp2.c: #include void foo(double x) { printf("%lld\n", (unsigned long long)(x * 10)); } If I link testfp.d against testfp2.c, then it outputs 12. If I link against testfp2.d, it outputs 11. I have faith that printf and writeln properly output ulongs. Something different happens with the cast. There can be no constant folding operations or optimizations going on here, as this is done via separate compilation. I'll re-open the bug report. -Steve
Re: Casting double to ulong weirdness
On Monday, 24 August 2015 at 18:16:44 UTC, Justin Whear wrote: On Mon, 24 Aug 2015 18:06:07 +, rumbu wrote: BTW, 1.2 and 12.0 are directly representable as double In C++: printf("%.20f\r\n", 1.2); printf("%.20f\r\n", 12.0); will output: 1.2000 12. Either upcasting to real is the wrong decision here, either the writeln string conversion is wrong. No it's not, this must be some sort of constant-folding or precision increase. Maybe the constant folding is using a different rounding mode to the runtime?
Re: Casting double to ulong weirdness
On Monday, 24 August 2015 at 18:06:08 UTC, rumbu wrote: BTW, 1.2 and 12.0 are directly representable as double 12.0 is representable, but I'm pretty sure, if you work it out, 1.2 isn't.
Re: Casting double to ulong weirdness
On 08/24/2015 11:06 AM, rumbu wrote: > BTW, 1.2 and 12.0 are directly representable as double 12 is but 1.2 is not. > In C++: > > printf("%.20f\r\n", 1.2); > printf("%.20f\r\n", 12.0); > > will output: > > 1.2000 > 12. > > Either upcasting to real is the wrong decision here, either the writeln > string conversion is wrong. Output is one thing. The issue is with the representation of 1.2. You need infinite digits. D's %a helps with visualizing it: import std.stdio; void main() { writefln("%a", 1.2); writefln("%a", 12.0); } Outputs 0x1.3p+0 0x1.8p+3 Ali
Re: Casting double to ulong weirdness
On Mon, 24 Aug 2015 18:06:07 +, rumbu wrote: > BTW, 1.2 and 12.0 are directly representable as double > > In C++: > > printf("%.20f\r\n", 1.2); > printf("%.20f\r\n", 12.0); > > will output: > > 1.2000 12. > > Either upcasting to real is the wrong decision here, either the writeln > string conversion is wrong. No it's not, this must be some sort of constant-folding or precision increase. $ cat test.c #include "stdio.h" int main(int nargs, char** args) { double x = 1.2; printf("%.20f\n", x); } $ clang test.c && ./a.out 1.19995559
Re: Casting double to ulong weirdness
BTW, 1.2 and 12.0 are directly representable as double In C++: printf("%.20f\r\n", 1.2); printf("%.20f\r\n", 12.0); will output: 1.2000 12. Either upcasting to real is the wrong decision here, either the writeln string conversion is wrong.
Re: Casting double to ulong weirdness
On Monday, 24 August 2015 at 17:26:12 UTC, Steven Schveighoffer wrote: Note, this is NOT a D problem, this is a problem with floating ponit. And by problem, I mean feature-that-you-should-avoid :) -Steve Visual C++ 19.00.23026, x86, x64: int _tmain(int argc, _TCHAR* argv[]) { double x = 1.2; printf("%d\r\n", (unsigned long long)(x * 10.0)); double y = 1.2 * 10.0; printf("%d\r\n", ((unsigned long long)y)); return 0; } Output: 12 12 Same output in debugger for an ARM Windows App. C# 6.0: static void Main(string[] args) { double x = 1.2; WriteLine((ulong)(x * 10.0)); double y = 1.2 * 10.0; WriteLine((ulong)y); } Output: 12 12 Same output in debugger for ARM in all flavours (Android, iOS, Windows) It seems like a D problem.
Re: Casting double to ulong weirdness
On Monday, 24 August 2015 at 17:26:12 UTC, Steven Schveighoffer wrote: On 8/24/15 12:52 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" \"" wrote: I'm posting this here for visibility. This was silently corrupting our data, and might be doing the same for others as well. import std.stdio; void main() { double x = 1.2; writeln(cast(ulong)(x * 10.0)); double y = 1.2 * 10.0; writeln(cast(ulong)y); } Output: 11 12 Yes. This is part of the issue of floating point. 1.2 cannot be represented accurately. The second case is done via real, not double, and at compile time (i.e. constant folding). There may be other reasons why this works. You are better off adding a small epsilon: writeln(cast(ulong)(x * 10.0 + 0.1)); to!ulong instead of the cast does the right thing, and is a viable work-around. to!ulong likely adds the epsilon, but you'd have to look to be sure. Note, this is NOT a D problem, this is a problem with floating point. And by problem, I mean feature-that-you-should-avoid :) -Steve I am familiar with floating-point representations and their pitfalls, and I think that is not the issue here. The issue I am trying to illustrate is the fact that the same exact operation returns different results. Both operations are x * 10.0, except one of them passes through the stack before the cast. I would expect this to be consistent, as I believe is the case in C/C++.
Re: Casting double to ulong weirdness
On Monday, 24 August 2015 at 16:52:54 UTC, Márcio Martins wrote: I'm posting this here for visibility. This was silently corrupting our data, and might be doing the same for others as well. import std.stdio; void main() { double x = 1.2; writeln(cast(ulong)(x * 10.0)); double y = 1.2 * 10.0; writeln(cast(ulong)y); } Output: 11 12 to!ulong instead of the cast does the right thing, and is a viable work-around. Issue: https://issues.dlang.org/show_bug.cgi?id=14958) I would not describe to!ulong as a "work-around". You just discovered one of the reasons to! exists: it is the right way to do it and cast(ulong) is the wrong way. As the others have noted, floating point is tricky business, and you need to use the right tools for the job. std.math.round also works.
Re: Casting double to ulong weirdness
On 8/24/15 12:52 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" \"" wrote: I'm posting this here for visibility. This was silently corrupting our data, and might be doing the same for others as well. import std.stdio; void main() { double x = 1.2; writeln(cast(ulong)(x * 10.0)); double y = 1.2 * 10.0; writeln(cast(ulong)y); } Output: 11 12 Yes. This is part of the issue of floating point. 1.2 cannot be represented accurately. The second case is done via real, not double, and at compile time (i.e. constant folding). There may be other reasons why this works. You are better off adding a small epsilon: writeln(cast(ulong)(x * 10.0 + 0.1)); to!ulong instead of the cast does the right thing, and is a viable work-around. to!ulong likely adds the epsilon, but you'd have to look to be sure. Note, this is NOT a D problem, this is a problem with floating point. And by problem, I mean feature-that-you-should-avoid :) -Steve
Re: Sub forum for dmd implementation details
On 8/24/15 1:00 PM, Benjamin Thaut wrote: As a occasional contributor to dmd I usually manage to get everything working the way I want by digging through the dmd source code long enough, but sometimes bad / non-existing documentation and missing knowdelge result in suboptimal solutions or unsolved problems. I would greatly appreciate a subforum which purpose it is to discuss compiler implementation details. I know that there is dmd-internals, but it seems that this forum only gets spammed by some bot with pull-request messages. Questions asked there do get answered. Most of the developers access it via a mailing list, and it's pretty easy to filter out the github messages from the real stuff. -Steve
Re: Casting double to ulong weirdness
On Monday 24 August 2015 18:52, wrote: > import std.stdio; > void main() { >double x = 1.2; >writeln(cast(ulong)(x * 10.0)); >double y = 1.2 * 10.0; >writeln(cast(ulong)y); > } > > Output: > 11 > 12 > > > to!ulong instead of the cast does the right thing, and is a > viable work-around. > > Issue: https://issues.dlang.org/show_bug.cgi?id=14958) 1.2 is not representable exactly in binary. Try printing it with a lot of decimal places: writefln("%.20f", x); /* prints "1.19995559" */ Multiply that by 10: ~11.999; cast to ulong: 11. Interestingly, printing x * 10.0 that way shows exactly 12: writefln("%.20f", x * 10.0); /* 12. */ But cast one operand to real and you're back at 11.9...: writefln("%.20f", cast(real)x * 10.0); /* 11.99955591 */ So, apparently, real precision is used in your code. This is not unexpected; compilers are allowed to use higher precision than requested for floating point operations. I think people have argued against it in the past, but so far Walter has been adamant about it being the right choice.
Re: dmd codegen improvements
On Monday, 24 August 2015 at 15:36:42 UTC, ixid wrote: -snip- Yes, it requires someone to pick up the baton for what is clearly a very significant task. Your site is excellent and it's very unfortunate that D is absent. iirc I asked Peter Alexander about progress last December and he had successfully used the provided scripts without any difficulty. Someone has published a Python comparison website (even re-using the PHP scripts as-is!) without needing to ask me any questions at all -- http://pybenchmarks.org/ It just needs "someone to pick up the baton" and do it, instead of talking about doing it.
Sub forum for dmd implementation details
As a occasional contributor to dmd I usually manage to get everything working the way I want by digging through the dmd source code long enough, but sometimes bad / non-existing documentation and missing knowdelge result in suboptimal solutions or unsolved problems. I would greatly appreciate a subforum which purpose it is to discuss compiler implementation details. I know that there is dmd-internals, but it seems that this forum only gets spammed by some bot with pull-request messages. Kind Regards Benjamin Thaut
Casting double to ulong weirdness
I'm posting this here for visibility. This was silently corrupting our data, and might be doing the same for others as well. import std.stdio; void main() { double x = 1.2; writeln(cast(ulong)(x * 10.0)); double y = 1.2 * 10.0; writeln(cast(ulong)y); } Output: 11 12 to!ulong instead of the cast does the right thing, and is a viable work-around. Issue: https://issues.dlang.org/show_bug.cgi?id=14958)
Re: dmd codegen improvements
On Monday, 24 August 2015 at 15:03:48 UTC, Isaac Gouy wrote: On Monday, 24 August 2015 at 08:59:57 UTC, ixid wrote: -snip- People love competitions, the current benchmark site that seems to weirdly dislike D is one of people's go to references. I do not have the ability to do this but it would seem like an excellent project for someone outside the major development group, a Summer of Code-esque thing. Lest we forget, this time last year -- http://forum.dlang.org/post/lv9s7n$1trl$1...@digitalmars.com Yes, it requires someone to pick up the baton for what is clearly a very significant task. Your site is excellent and it's very unfortunate that D is absent.
Re: dmd codegen improvements
On Monday, 24 August 2015 at 13:45:58 UTC, jmh530 wrote: You mean this site? http://benchmarksgame.alioth.debian.org/ Yes, precisely that but try to one up it with more challenges.
Re: dmd codegen improvements
On Monday, 24 August 2015 at 08:59:57 UTC, ixid wrote: -snip- People love competitions, the current benchmark site that seems to weirdly dislike D is one of people's go to references. I do not have the ability to do this but it would seem like an excellent project for someone outside the major development group, a Summer of Code-esque thing. Lest we forget, this time last year -- http://forum.dlang.org/post/lv9s7n$1trl$1...@digitalmars.com
Re: string <-> null/bool implicit conversion
On Friday, 21 August 2015 at 11:34:42 UTC, Marc Schütz wrote: On Thursday, 20 August 2015 at 19:41:44 UTC, Jonathan M Davis wrote: On Thursday, 20 August 2015 at 17:50:11 UTC, Steven Schveighoffer wrote: if(arr != null) Definitely don't do that. IMHO, "== null and "!= null" should be illegal. If you really want to check for null, then you need to use "is null" or "!is null", whereas if you want to check that an array is empty, check its length or call empty. By using "== null" or "!= null", you tend to give the false impression that you're checking whether the object or array is null - which is not what you're actually doing. I disagree. `is null` is the one that should be illegal. `is` is supposed to do a bitwise comparison, but `null` is usually just a pointer/reference, while a slice consists of both a reference and a length. Which of those are compared? No ambiguity there: D doesn't allow comparison of array with pointer.
Re: string <-> null/bool implicit conversion
On Friday, 21 August 2015 at 20:01:21 UTC, Vladimir Panteleev wrote: "This warning almost doesn't break any code!" Yes it flipping does. "It does break some code, but only in certain extremely specialized contexts like memory allocation!" No it's bleeping not. "Many of those warnings are probably actual bugs, you should fix your buggy code!" No, they quacking aren't. I just write code this way, because I find the empty/null distinction obvious and useful. Shocking, I know. The distinction has its merits, but it shouldn't prevent you from seeing how it doesn't quite fit the D slice design.
Re: string <-> null/bool implicit conversion
On Saturday, 22 August 2015 at 21:23:19 UTC, Timon Gehr wrote: For the comma operator, I think it's pretty clear that the usage of ',' to separate components of a tuple would be more useful. Why not use C/C++/C# initializer syntax? Technically it's a tuple, but not related to comma operator.
Re: dmd codegen improvements
On Monday, 24 August 2015 at 08:59:57 UTC, ixid wrote: One of D's potential massive wins is speed and I think that has the most easily conveyed impacted on the audience. If we had the best benchmark site for a very large range of languages it would not only draw people here but drive the improvement of D on all compilers (and perhaps allow us to make LDC/GCD for run speed, DMD for compile speed more explicit) as every time there is a benchmark contest we seem to find some small thing that needs a fix and then D blows others away. This would also convey more idiomatic D for performance as D seems to suffer from people writing it as whatever language they come from. People love competitions, the current benchmark site that seems to weirdly dislike D is one of people's go to references. I do not have the ability to do this but it would seem like an excellent project for someone outside the major development group, a Summer of Code-esque thing. You mean this site? http://benchmarksgame.alioth.debian.org/
Re: [OT] Sharp Regrets: Top 10 Worst C# Features
On 19/08/15 15:01, Kagamin wrote: Just switch your editor to RTL mode, haha. OT: (so this is an off topic reply to an off topic thread) I actually tried to write a good RTL text editor (you can see the half baked result at http://bidiedit.lingnu.com). I know your comment was meant as a joke, but the truth is that mixing RTL text with code does not work well in any editor I have ever encountered. The BiDi engine is located too low to incorporate the syntax analysis required to do it properly (and, in some cases, it is not clear what "properly" even means) for any editor I've seen to do it. I usually end up using VIM, because it does not reoredering at all (I.e. - all text, regardless of language, is shown from left to right), which means that I can separate syntax from content. Shachar
Re: [OT] Sharp Regrets: Top 10 Worst C# Features
On Thursday, 20 August 2015 at 16:22:22 UTC, Jonathan M Davis wrote: I really don't mind NaN. Well with silent NaN you have 'x == x' is false which means all the generic algorithms (silently) fail. It really doesn't cause problems normally. The problem with floating point values is floating > point values themselves. They're so painfully inexact. Even without NaN, you can't use == with them and expect it to work. Compared to that, how NaN is dealt with is a total non-issue. Floating points themselves just plain suck. They're sometimes necessary, but they suck. - Jonathan M Davis I think that at Sun some pushed for interval arithmetic support, but 1) Oracle has bought Sun 2) range has its own set of problem and they are more expensive to compute. I'm still a bit sad that modern CPU seems to spend their humongous amount of transistors on dubious feature yet they don't try to support important basic things such as 'trap on overflow' integer computations, interval arithmetic.
Re: associative arrays with manual memory management
On Saturday, 22 August 2015 at 04:16:30 UTC, Rikki Cattermole wrote: On 8/22/2015 5:20 AM, Ilya Yaroshenko wrote: Hi All! I am going to implement associative arrays with manual memory management based on amazing std.experimental.allocator by Andrei http://wiki.dlang.org/Review/std.experimental.allocator I will be happy to receive any advices about algorithms, use cases and API. Best Regards, Ilya Will it be language feature fix, or is it an independent container? If the later I already have a simple dumb one which I can share (not on this machine). I'll be happy to use what you create. Same goes for list and friends ones. Annonce http://forum.dlang.org/post/hgawkhhbvkkxbnjzi...@forum.dlang.org
Re: extern opaque struct
On Monday, 24 August 2015 at 04:08:28 UTC, Daniel Murphy wrote: "John Colvin" wrote in message news:uhpgjffttsuqeswyj...@forum.dlang.org... Let's say I have some C headers that have code like this in: extern struct UndeclaredStruct blah; Undeclared *p = &blah; which would naïvely translate to D as: struct UndeclaredStruct; extern UndeclaredStruct blah; auto p = &blah; which doesn't compile. Why not? Neither the size nor any default initialiser is needed. It should work, please file in bugzilla. done: https://issues.dlang.org/show_bug.cgi?id=14954
Re: [OT] Sharp Regrets: Top 10 Worst C# Features
On Friday, 21 August 2015 at 19:58:04 UTC, Tobias Müller wrote: "Chris" wrote: [...] As if most people were too stpid to grasp the concept that `x++` is the same as `x += 1` (which is intellectually as 'challenging' as `x++`, by the way). Because it's not. ++x is the same as x+=1, not x++. Tobi This distinction is only relevant if there are two variables involved (i.e. assignment): `y = x++;` where `y = ++x;` does in fact yield a different result (most likely the desired one). If you work on the same variable, `x++;` is fine. Thus, I don't agree with Python's philosophy.
Re: dmd codegen improvements
On Tuesday, 18 August 2015 at 10:45:49 UTC, Walter Bright wrote: Martin ran some benchmarks recently that showed that ddmd compiled with dmd was about 30% slower than when compiled with gdc/ldc. This seems to be fairly typical. I'm interested in ways to reduce that gap. One of D's potential massive wins is speed and I think that has the most easily conveyed impacted on the audience. If we had the best benchmark site for a very large range of languages it would not only draw people here but drive the improvement of D on all compilers (and perhaps allow us to make LDC/GCD for run speed, DMD for compile speed more explicit) as every time there is a benchmark contest we seem to find some small thing that needs a fix and then D blows others away. This would also convey more idiomatic D for performance as D seems to suffer from people writing it as whatever language they come from. People love competitions, the current benchmark site that seems to weirdly dislike D is one of people's go to references. I do not have the ability to do this but it would seem like an excellent project for someone outside the major development group, a Summer of Code-esque thing.
Re: Ruby 3.0 to have immutable strings by default / C++ heading towards "generic all the time".
On Thursday, 20 August 2015 at 22:07:10 UTC, John Carter wrote: https://twitter.com/yukihiro_matz/status/634386185507311616 Pity that concepts looks to be a very painful syntax for expressing what D does so clearly. One big difference is that C++1z concepts are supposed to allow looking for external functions, not only methods. That would require some kind of principled hijacking of templates in Dlang (or else the constraint template would keep looking for the functions, called by ufcs, either inside the type of in the templates declaration position). I haven't managed to work that out yet except by using mixins :/
Re: front-page examples not working
On Monday, 24 August 2015 at 07:27:29 UTC, Øivind wrote: I love the new examples on the front-page, but when I click the "run" button, I get this error: /d982/f573.d(32): Error: undefined identifier centerJustifier I got a different error on one of the other new examples yesterday. Please make sure these work. They are a great showcase of the language. It's because it uses DPaste to run and DPaste compiler is seriously outdated. (same problem for a user using 2.066.1 http://forum.dlang.org/post/aqoyjlykqywjkvxde...@forum.dlang.org) DPaste is at 2.065 see also: http://forum.dlang.org/thread/mr5da0$1djk$1...@digitalmars.com
front-page examples not working
I love the new examples on the front-page, but when I click the "run" button, I get this error: /d982/f573.d(32): Error: undefined identifier centerJustifier I got a different error on one of the other new examples yesterday. Please make sure these work. They are a great showcase of the language.
Re: Ruby 3.0 to have immutable strings by default / C++ heading towards "generic all the time".
On 2015-08-24 08:35, rsw0x wrote: implement this in D https://github.com/solodon4/Mach7 It's just a matter of syntax. -- /Jacob Carlborg