Re: Problem with object understanding and datatypes

2013-06-23 Thread Nordlöw

Is this code available in any repo/archive somewhere?

/Per


Re: Problem with object understanding and datatypes

2013-05-25 Thread Ali Çehreli

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

2013-05-25 Thread Namal

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

2013-05-25 Thread Namal

Thanks, that helped me alot.


Re: Problem with object understanding and datatypes

2013-05-25 Thread Ali Çehreli

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

2013-05-25 Thread Namal

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

2013-05-25 Thread bearophile

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

2013-05-25 Thread Namal

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

2013-05-24 Thread Juan Manuel Cabo

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

2013-05-24 Thread Namal


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

2013-05-24 Thread Ali Çehreli

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

2013-05-24 Thread Namal
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.