www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - float price; if (price == float.nan) { // initialized } else { //

reply someone <someone somewhere.com> writes:
Is the following code block valid ?

```d
float price; /// initialized as float.nan by default ... right ?

if (price == float.nan) {

    /// writeln("initialized");

} else {

    /// writeln("uninitialized");

}
```

if so, the following one should be valid too ... right ?

```d
float price;

if (price != float.nan) {

    /// writeln("initialized");

}
```
Jun 29
next sibling parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Wednesday, 30 June 2021 at 03:15:46 UTC, someone wrote:
 Is the following code block valid ?
Comparison with `nan` always results in `false`: See section 10.11.5: https://dlang.org/spec/expression.html#equality_expressions You can use the `is` operator to perform bitwise comparison, or use `std.math.isNaN`.
Jun 29
next sibling parent reply Mathias LANG <geod24 gmail.com> writes:
On Wednesday, 30 June 2021 at 03:32:27 UTC, Vladimir Panteleev 
wrote:
 On Wednesday, 30 June 2021 at 03:15:46 UTC, someone wrote:
 Is the following code block valid ?
Comparison with `nan` always results in `false`: See section 10.11.5: https://dlang.org/spec/expression.html#equality_expressions You can use the `is` operator to perform bitwise comparison, or use `std.math.isNaN`.
Side note: That doesn't apply to `if (myFloat)` or `assert(myFloat);`, unfortunately: https://issues.dlang.org/show_bug.cgi?id=13489
Jun 29
parent reply someone <someone somewhere.com> writes:
On Wednesday, 30 June 2021 at 03:51:47 UTC, Mathias LANG wrote:

 or use `std.math.isNaN`.
```d import std.math : isNaN; float lnumStockPricePreceding; foreach (float lnumStockPrice; ludtStockPriceEvolution.range) if (! isNan(lnumStockPricePreceding)) { /// do something } lnumStockPricePreceding = lnumStockPrice; } ``` ... is far from pretty but it works as expected, thanks for your tip !
Jun 29
parent Mathias LANG <geod24 gmail.com> writes:
On Wednesday, 30 June 2021 at 04:03:24 UTC, someone wrote:
 On Wednesday, 30 June 2021 at 03:51:47 UTC, Mathias LANG wrote:

 ... is far from pretty but it works as expected, thanks for 
 your tip !
Can be made a bit prettier with UFCS:
 ```d
 import std.math : isNaN;

 float lnumStockPricePreceding;

 foreach (float lnumStockPrice; ludtStockPriceEvolution.range)

    if (!lnumStockPricePreceding.isNan) {

       /// do something

    }

    lnumStockPricePreceding = lnumStockPrice;

 }
 ```
Or even better, with ranges:
 ```d
 import std.math : isNaN;

 float lnumStockPricePreceding;

 foreach (float lnumStockPrice; 
 ludtStockPriceEvolution.range.filter!(f => !f.isNan))
       /// do something

    lnumStockPricePreceding = lnumStockPrice;

 }
 ```
Jun 29
prev sibling parent reply someone <someone somewhere.com> writes:
On Wednesday, 30 June 2021 at 03:32:27 UTC, Vladimir Panteleev 
wrote:

 Comparison with `nan` always results in `false`:
THAT explains a lot !
 See section 10.11.5:
missed it. One of the things I do not like with D, and it causes me to shoot me on the foot over and over, is the lack of null for *every* data type. Things like: ```d float lnumStockPricePreceding = null; foreach (float lnumStockPrice; ludtStockPriceEvolution.range) if (lnumStockPricePreceding ! is null) { /// do something } lnumStockPricePreceding = lnumStockPrice; } ``` ... were first attempted like following on D: ```d float lnumStockPricePreceding; foreach (float lnumStockPrice; ludtStockPriceEvolution.range) if (lnumStockPricePreceding != float.nan) { /// do something } lnumStockPricePreceding = lnumStockPrice; } ``` ... and now need to be recoded like: ```d float lnumStockPricePreceding = 0f; foreach (float lnumStockPrice; ludtStockPriceEvolution.range) if (lnumStockPricePreceding != 0f) { /// do something } lnumStockPricePreceding = lnumStockPrice; } ``` ... which oftenly complicates things because sometimes even 0f is a valid value for the task at hand and thus I MISS NULLs A LOT :( ... at least I can do nulls with strings since it a class :)
Jun 29
next sibling parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Wednesday, 30 June 2021 at 03:52:51 UTC, someone wrote:
 One of the things I do not like with D, and it causes me to 
 shoot me on the foot over and over, is the lack of null for 
 *every* data type. Things like:
If you want to give any type a "null" value, you could use [`std.typecons.Nullable`](https://dlang.org/library/std/typecons/nullable.html).
Jun 29
next sibling parent someone <someone somewhere.com> writes:
On Wednesday, 30 June 2021 at 03:55:05 UTC, Vladimir Panteleev 
wrote:

 If you want to give any type a "null" value, you could use
[`std.typecons.Nullable`](https://dlang.org/library/std/typecons/nullable.html). Practically Nullable!T stores a T and a bool. I like the idea :)
Jun 29
prev sibling parent reply someone <someone somewhere.com> writes:
On Wednesday, 30 June 2021 at 03:55:05 UTC, Vladimir Panteleev 
wrote:

 If you want to give any type a "null" value, you could use
[`std.typecons.Nullable`](https://dlang.org/library/std/typecons/nullable.html). At LEAST for some things with currency types like prices which cannot be zero because 0 makes no sense for a price: Nullable!(T, nullValue) is more storage-efficient than Nullable!T because it does not need to store an extra bool. This could come handly. We'll see.
Jun 29
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Wednesday, 30 June 2021 at 04:17:19 UTC, someone wrote:
 On Wednesday, 30 June 2021 at 03:55:05 UTC, Vladimir Panteleev 
 wrote:

 If you want to give any type a "null" value, you could use
[`std.typecons.Nullable`](https://dlang.org/library/std/typecons/nullable.html). At LEAST for some things with currency types like prices which cannot be zero because 0 makes no sense for a price: [snip]
You've never given something away for free?
Jun 30
parent reply someone <someone somewhere.com> writes:
On Wednesday, 30 June 2021 at 10:38:05 UTC, jmh530 wrote:

 You've never given something away for free?
... more often than usual LoL Now, seriously, something for free has not a price = 0, it has NO price, that's what null is for; we use zero for the lack of null.
Jun 30
parent bauss <jj_1337 live.dk> writes:
On Wednesday, 30 June 2021 at 16:19:35 UTC, someone wrote:
 On Wednesday, 30 June 2021 at 10:38:05 UTC, jmh530 wrote:

 You've never given something away for free?
... more often than usual LoL Now, seriously, something for free has not a price = 0, it has NO price, that's what null is for; we use zero for the lack of null.
Actually a price can be 0, say if you have a sale that gives 100 % off then the price doesn’t magically disappear. It could be that the 100 % off is only for specific people or businesses. Or that they pay fees instead of the price of a product, in which case there’s a fee price but a product with the price of 0 because otherwise you’ll have accounting problems since you can’t make accounting on records without prices, because mathematically that makes no sense.
Jul 08
prev sibling parent reply Dennis <dkorpel gmail.com> writes:
On Wednesday, 30 June 2021 at 03:52:51 UTC, someone wrote:
 at least I can do nulls with strings since it a class :)
A `string` is not a class but an array, an `immutable(char)[]`. For arrays, `null` is equal to an empty array `[]`. ```D void main() { string s0 = null; string s1 = []; assert(s0 == s1); assert(s0.length == 0); // no null dereference here } ```
Jun 30
parent someone <someone somewhere.com> writes:
On Wednesday, 30 June 2021 at 09:36:34 UTC, Dennis wrote:

 A `string` is not a class but an array, an `immutable(char)[]`.
You're right. My fault.
Jun 30
prev sibling parent reply Andre Pany <andre s-e-a-p.de> writes:
On Wednesday, 30 June 2021 at 03:15:46 UTC, someone wrote:
 Is the following code block valid ?

 ```d
 float price; /// initialized as float.nan by default ... right ?

 if (price == float.nan) {

    /// writeln("initialized");

 } else {

    /// writeln("uninitialized");

 }
 ```

 if so, the following one should be valid too ... right ?

 ```d
 float price;

 if (price != float.nan) {

    /// writeln("initialized");

 }
 ```
Side note: in case you want to work with money, you may consider using a specific data type like https://code.dlang.org/packages/money instead of float/double. Kind regards Andre
Jun 30
parent reply someone <someone somewhere.com> writes:
On Wednesday, 30 June 2021 at 16:24:38 UTC, Andre Pany wrote:

 Side note: in case you want to work with money, you may 
 consider using a specific data type like 
 https://code.dlang.org/packages/money instead of float/double.
Yes, I've seen it, and in a previous-unrelated post I commented I am planning to use it (or something similar) because floats and currency are a horrible combo. I am not using it right now because I want to learn the language and encountering situations like this one helps me a lot, otherwise, I would have never noted such NaN behavior -to me, there are a lots of things that could fly under the radar at this moment. And by the way, looking at the code, money seems a quite simple non-nonsense implementation making it a solid candidate :) Thanks for the tip Andre !
Jun 30
parent bauss <jj_1337 live.dk> writes:
On Wednesday, 30 June 2021 at 16:41:40 UTC, someone wrote:
 On Wednesday, 30 June 2021 at 16:24:38 UTC, Andre Pany wrote:

 Side note: in case you want to work with money, you may 
 consider using a specific data type like 
 https://code.dlang.org/packages/money instead of float/double.
Yes, I've seen it, and in a previous-unrelated post I commented I am planning to use it (or something similar) because floats and currency are a horrible combo. I am not using it right now because I want to learn the language and encountering situations like this one helps me a lot, otherwise, I would have never noted such NaN behavior -to me, there are a lots of things that could fly under the radar at this moment. And by the way, looking at the code, money seems a quite simple non-nonsense implementation making it a solid candidate :) Thanks for the tip Andre !
What you actually should do when working with money which is what a lot of banking solutions etc. do is working with cents only in 2 decimal places. So 25.98 would be represented as 2598. It makes sure that you’ll never have rounding errors or floating point representations that are wrong.
Jul 08