www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - possible bug in std.conv.parse

reply "ketmar" <ketmar ketmar.no-ip.org> writes:
this code: std.conv.parse!byte("-128") throws error: "Overflow in 
integral conversion". but this is obviously not true, as signed 
byte can hold such value.

the question is: is it bug, or it's intended behavior to limit 
signed integrals to values which can be safely abs()ed?
Apr 26 2014
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Saturday, 26 April 2014 at 23:36:28 UTC, ketmar wrote:
 this code: std.conv.parse!byte("-128") throws error: "Overflow 
 in integral conversion". but this is obviously not true, as 
 signed byte can hold such value.

Check your math... the most negative number a signed byte can hold is -127. The most positive number it can hold is 128, but negating that wouldn't fit in eight bits.
Apr 26 2014
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 04/27/2014 01:43 AM, Adam D. Ruppe wrote:
 On Saturday, 26 April 2014 at 23:36:28 UTC, ketmar wrote:
 this code: std.conv.parse!byte("-128") throws error: "Overflow in
 integral conversion". but this is obviously not true, as signed byte
 can hold such value.

Check your math... the most negative number a signed byte can hold is -127. The most positive number it can hold is 128, but negating that wouldn't fit in eight bits.

Check your math. :o)
Apr 26 2014
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/26/14, 4:43 PM, Adam D. Ruppe wrote:
 On Saturday, 26 April 2014 at 23:36:28 UTC, ketmar wrote:
 this code: std.conv.parse!byte("-128") throws error: "Overflow in
 integral conversion". but this is obviously not true, as signed byte
 can hold such value.

Check your math... the most negative number a signed byte can hold is -127. The most positive number it can hold is 128, but negating that wouldn't fit in eight bits.

Oops. No bug. -- Andrei
Apr 26 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
ketmar:

 this code: std.conv.parse!byte("-128") throws error: "Overflow 
 in integral conversion". but this is obviously not true, as 
 signed byte can hold such value.

 the question is: is it bug, or it's intended behavior to limit 
 signed integrals to values which can be safely abs()ed?

This code works to me: void main() { import std.conv: to, parse; auto s1 = "-128"; assert(s1.parse!byte == -128); immutable s2 = "-128"; assert(s2.to!byte == -128); } What's your compiler version? Bye, bearophile
Apr 26 2014
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Saturday, 26 April 2014 at 23:43:11 UTC, Adam D. Ruppe wrote:
 Check your math

sorry, i should check my own math. I got it backwards, you're right.
Apr 26 2014
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/26/14, 4:36 PM, ketmar wrote:
 this code: std.conv.parse!byte("-128") throws error: "Overflow in
 integral conversion". but this is obviously not true, as signed byte can
 hold such value.

 the question is: is it bug, or it's intended behavior to limit signed
 integrals to values which can be safely abs()ed?

Bug. -- Andrei
Apr 26 2014
prev sibling next sibling parent "ketmar" <ketmar ketmar.no-ip.org> writes:
ah, sorry, this is my own fault, there is no bug in parser. what 
i'm doing is parse!byte("128") and then negating the result.

silly me.
Apr 26 2014
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Sunday, 27 April 2014 at 00:01:21 UTC, Andrei Alexandrescu 
wrote:
 Oops. No bug. -- Andrei

Nah, sorry, that was my giant mistake, I didn't actually do the math before saying "check your math" and let my brain get confused into thinking 10000000 was 128, but it is actually -128 in twos complement, the high bit is set so it is negative.
Apr 26 2014
prev sibling next sibling parent "ketmar" <ketmar ketmar.no-ip.org> writes:
On Sunday, 27 April 2014 at 00:04:15 UTC, ketmar wrote:
but this is definetely bug, i think:

void main() {
   import std.stdio : writeln;
   import std.conv : to;
   writeln(to!int("29a", 16)); // 666
   writeln(to!int("+29a", 16)); // Unexpected '+' when converting 
from type string base 16 to type int
   //writeln(to!int("-29a", 16)); // Unexpected '-' when 
converting from type string base 16 to type int
}


it compiles, but throws exceptions on last two lines with 
writeln(). base 10 accepts '+' and '-' though. why other bases 
aren't?
Apr 26 2014
prev sibling next sibling parent "ketmar" <ketmar ketmar.no-ip.org> writes:
ah, i see:  if (radix == 10) return parse!Target(s); in Target 
parse(Target, Source)(ref Source s, uint radix)

it cheating a little and using 'general' decimal number parser, 
which accepts '+' and '-'. for other bases it uses another code 
though, where '+' and '-' threats as digits, which leads to error.

i think that it should either not accept sign in any radix, or 
accept always (given the resulting type is signed, of course). 
the later is much more logical if you'll ask me.
Apr 26 2014
prev sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Sunday, 27 April 2014 at 00:07:22 UTC, Adam D. Ruppe wrote:
 On Sunday, 27 April 2014 at 00:01:21 UTC, Andrei Alexandrescu 
 wrote:
 Oops. No bug. -- Andrei

Nah, sorry, that was my giant mistake, I didn't actually do the math before saying "check your math" and let my brain get confused into thinking 10000000 was 128, but it is actually -128 in twos complement, the high bit is set so it is negative.

Yeah, or just remember that signed representation are evenly split between negatives and positives, but positives get the '0': Positives: [0 .. high); Negatives: [-high .. 0); It's an interesting source of bugs, and the reason you should "never" store an absolute value in a singed object. Since "-int.min" is still "int.min".
Apr 27 2014