Re: Problem with object understanding and datatypes
Is this code available in any repo/archive somewhere? /Per
Re: Problem with object understanding and datatypes
On 05/25/2013 11:57 AM, Namal wrote: > I have one more question towards using unsigned datatype > >assert(sint(-2_147_483_647) - sint(3) == sint(-2_147_483_648)); >assert(sint(-2_147_483_647) - sint(3) == sint(2_147_483_648)); > > Here I get an error for the second line, because it cannot be convertet It helps a lot if you tell the error message. After making some assumption I was able to produce an error message: Error: cannot implicitly convert expression (2147483648L) of type long to int It makes sense if sint is Saturated!int. 2147483648 is long but the struct member is int. > if i use unsigned > >assert(sint(-2_147_483_647) - sint(3) == sint(-2_147_483_648)); >assert(sint(-2_147_483_647) - sint(3) == sint(2_147_483_648u)); > > it makes no difference and I get an error. This time 2_147_483_648u is a uint which happens to have automatic conversion to int. Automatic type conversions can be extremely confusing. Let's see... import std.stdio; struct S { int i; } void main() { // uint converts to int: auto s = S(1u); int i; uint u = uint.max; // same: i = u; // Surprising result: assert(i == -1); } These rules are both because they are same or similar in C and also for convenience. But yes, they can be confusing... Ali
Re: Problem with object understanding and datatypes
I have one more question towards using unsigned datatype assert(sint(-2_147_483_647) - sint(3) == sint(-2_147_483_648)); assert(sint(-2_147_483_647) - sint(3) == sint(2_147_483_648)); Here I get an error for the second line, because it cannot be convertet if i use unsigned assert(sint(-2_147_483_647) - sint(3) == sint(-2_147_483_648)); assert(sint(-2_147_483_647) - sint(3) == sint(2_147_483_648u)); it makes no difference and I get an error. Why doesn't the minus sign matter here and how do I fix this? Especially where I have to use u assert(slong(-9_223_372_036_854_775_807) - slong(2) == slong(-9_223_372_036_854_775_808u)); assert(slong(-9_223_372_036_854_775_807) - slong(2) == slong(9_223_372_036_854_775_808u)); Also tried this with hex numbers but it is same with them.
Re: Problem with object understanding and datatypes
Thanks, that helped me alot.
Re: Problem with object understanding and datatypes
On 05/25/2013 04:34 AM, Namal wrote: > assert(slong(9_223_372_036_854_775_806) + slong(-3) == > slong(-9_223_372_036_854_775_808)); > } > > The first test is ok, but second wont even compile. Even if I append a L > to each number. According to the "Integer Literals" section here: http://dlang.org/lex.html Decimal literals are resolved as either int or long. 9_223_372_036_854_775_808 cannot fit either of those types. If you want ulong, you must either write the literal in hexadecimal or binary format or provide the UL suffix. Ali
Re: Problem with object understanding and datatypes
On Saturday, 25 May 2013 at 10:15:42 UTC, bearophile wrote: Namal: And if so, do I always have to use a suffix when the number is bigger than uint? It looks a bit silly, I agree. Bye, bearophile Well, now I have same Error for signed long: else{ static if (op == "+"){ if(rhs._value > T.init && T.max - rhs._value < _value) return rhs.max; else if(rhs._value < T.init && T.min - rhs._value > _value) return rhs.min; } static if (op == "-"){ if(rhs._value > T.init && T.min+rhs._value > _value) return rhs.min; else if(rhs._value < T.init && T.max + rhs._value < _value) return rhs.max; } static if (op == "/"){ if(rhs._value == -1) return rhs.max; } does work for every type exept long. Like for the addition unittest{ alias slong = Saturated!long; assert(slong(9_223_372_036_854_775_806) + slong(2) == slong(9_223_372_036_854_775_807)); assert(slong(9_223_372_036_854_775_806) + slong(-3) == slong(-9_223_372_036_854_775_808)); } The first test is ok, but second wont even compile. Even if I append a L to each number.
Re: Problem with object understanding and datatypes
Namal: And if so, do I always have to use a suffix when the number is bigger than uint? It looks a bit silly, I agree. Bye, bearophile
Re: Problem with object understanding and datatypes
Thank you very much, I thought the operators are alrdy checked by if (op == "+" || op == "-" || op == "/") But I did same tests for ushort uint and ulong, but for ulong it didn't compile. unittest{ alias sulong = Saturated!ulong; assert(sulong(18_446_744_073_709_551_610) + sulong(2) == sulong(18_446_744_073_709_551_612)); assert(sulong(18_446_744_073_709_551_614) + sulong(2) == sulong(18_446_744_073_709_551_615)); It failed to compile Error: signed integer overflow So I appended uL to each number and it worked. assert(sulong(18_446_744_073_709_551_610uL) + sulong(2uL) == sulong(18_446_744_073_709_551_612uL)); Was it the right idea to fix it? And if so, do I always have to use a suffix when the number is bigger than uint?
Re: Problem with object understanding and datatypes
On Saturday, 25 May 2013 at 01:03:53 UTC, Namal wrote: 255 - 129 is less than 128 so the result is T.max, which is 255, which is not equal to 0. I dont understand this at all 255 - 129 should be 126 in ubyte or not? I checked, and operation between two ubyte is an int. When you cast that int to ubyte, it gets its least significant byte represented as ubyte. import std.stdio; void main() { ubyte x = 128; ubyte y = 129; writeln(cast(ubyte)(x - y)); //prints 255 writeln(x - y); //prints -1 writeln(typeof(x - y).stringof); //prints 'int' } Also, I tried the code you pasted, and the reason it fails the asserts is that there's something wrong in the if conditions in opBinary (and also, that 'rhs.max - rhs._value' didn't compile). The following makes your asserts pass: ... static if (op == "-") { if(_value < rhs._value) return rhs.min; } static if (op == "+") { if(_value > max._value - rhs._value) return rhs.max; } ... --jm
Re: Problem with object understanding and datatypes
255 - 129 is less than 128 so the result is T.max, which is 255, which is not equal to 0. I dont understand this at all 255 - 129 should be 126 in ubyte or not?
Re: Problem with object understanding and datatypes
On 05/24/2013 01:19 PM, Namal wrote: > if(rhs.max - rhs._value < _value) I had a compilation error so I had to change that line to the following: if(T.max - rhs._value < _value){ > assert(subyte(128) - subyte(129) == subyte(0)); > } > > But the last test does not pass. 255 - 129 is less than 128 so the result is T.max, which is 255, which is not equal to 0. > Why does the minus operation is treated in signed datatype, while + is > unsigned? I don't think that is happening at all but the rules can get pretty confusing. See "Integer Promotions" and "Usual Arithmetic Conversions" should be known in general: :) http://dlang.org/type.html Ali
Problem with object understanding and datatypes
So the task is to write a struct object for the saturation arithmetic. I tried first to write it for the unsigned Types: struct Saturated(T) if (isIntegral!T) { static assert (isUnsigned!T || isSigned!T); @property { static Saturated min() { return Saturated(T.min); } static Saturated max() { return Saturated(T.max); } static Saturated init() { return Saturated(T.init); } } Saturated opBinary(string op)(const Saturated rhs) const if (op == "+" || op == "-" || op == "/") { static if (isUnsigned!T){ if(rhs.max - rhs._value < _value) return rhs.max; if(rhs._value > _value) return rhs.min; return Saturated(cast(T)(mixin("_value " ~ op ~ " rhs._value"))); } else{ return Saturated(cast(T)(mixin("_value " ~ op ~ " rhs._value"))); } } string toString() const { import std.conv; return to!string(_value); } private: T _value; } unittest { alias subyte = Saturated!ubyte; assert(subyte(254) + subyte(2) == subyte(255)); assert(subyte(100) + subyte(2) == subyte(102)); assert(subyte(10) - subyte(11) == subyte(0)); assert(subyte(128) - subyte(129) == subyte(0)); } But the last test does not pass. Why does the minus operation is treated in signed datatype, while + is unsigned? Note that I do not know much about templates or methods. So pls execuse me if I do a major mistake here.