moderated >> 2's complement usage in Perl

by stylechief » Fri, 08 Apr 2005 05:46:20 GMT

I need to recognize a 2's complement hex number and render it as a
signed integer. ex: ffbe8e should render as -16754, not 16760462.

I have not found any Perl function that correctly identifies a 2's
complement hex number.

Suggestions/solutions, please.

Thank you,
Liam

moderated >> 2's complement usage in Perl

by John Bokma » Fri, 08 Apr 2005 13:08:12 GMT



correct it if the value is above a certain threshold.

--
John MexIT: http://johnbokma.com/mexit/
personal page: http://johnbokma.com/
Experienced programmer available: http://castleamber.com/
Happy Customers: http://castleamber.com/testimonials.html

moderated >> RE: 2's complement usage in Perl

by Thomas, Mark - BLS CTR » Fri, 08 Apr 2005 21:05:10 GMT


Bit::Vector should be able to do it.

- Mark.

moderated >> 2's complement usage in Perl

by Keith Thompson » Sat, 09 Apr 2005 04:01:15 GMT

"stylechief" < XXXX@XXXXX.COM > writes:

It's not clear (to me) what problem you're trying to solve.

What does it mean for a string of hex digits, such as ffbe8e, to be a
"2's complement hex number"? Before trying to implement in Perl, can
you describe it in English?

I don't see anything about ffbe8e that marks as being 2's complement.
If you assume it's the representation of a 24-bit integer with a 2's
complement representation, its value is -16754; if it's more than 24
bits (say, 32), the value is 16760462.

What determines the number of bits? If it's the number of hex digits,
then anything with a leading digit of 8 or more is a negative value;
ffbe8e becomes -16754, and 0ffbe8e becomes 16760462. Apply the "hex"
function to the string; if you want it to be negative, subtract
2**(4 * length $s).

--
Keith Thompson (The_Other_Keith) XXXX@XXXXX.COM < http://www.ghoti.net/ ~kst>
San Diego Supercomputer Center <*> < http://users.sdsc.edu/ ~kst>
We must do something. This is something. Therefore, we must do this.

moderated >> 2's complement usage in Perl

by Liam » Mon, 11 Apr 2005 23:25:30 GMT

The 2's complement is a method for representing integers in binary that
seems to be common in many operating systems and programming languages.
It is considered to be an easy way to represent negative integers.
Here's one description:
http://www.evergreen.edu/biophysics/technotes/program/2s_comp.htm
It appears that Perl does not 'natively' assume 2's complement like
some other languages. If the binary representation starts with a zero,
then the number is positive, if it starts with a 1, then it is
negative. If one needs to deal with 32 bit or larger numbers, simply
pad with 1's or 0's.

digits,
< http://www.ghoti.net/ ~kst>
< http://users.sdsc.edu/ ~kst>
this.

moderated >> 2's complement usage in Perl

by Liam » Tue, 12 Apr 2005 07:03:36 GMT

Quote from the Bit::Vector module:
"As a consequence, whenever you pass a negative number as an argument
to some method of this module, it will be treated as a (usually very
large) positive number due to its internal two's complement binary
representation, usually resulting in an "index out of range" error
message and program abortion."

Still searching . . . .

moderated >> 2's complement usage in Perl

by Alan J. Flavell » Tue, 12 Apr 2005 08:14:21 GMT

On Mon, Apr 11, Liam blurted out atop a fullquote:


I'd say it's more in the nature of a hardware implementation issue, if
you want to take the broader view.

I think Perl, on the whole, takes a higher-level view of data; but if
you know what you're doing, it's possible, in Perl, to assemble a bit
pattern (i.e with bitwise operators) and then interpret it as a signed
integer. But I've been doing that since long before I ever met Perl.

On the other hand, sometimes one needs 32-bit data interpreted as a
positive number. I'm sure you appreciate that it can't be both at the
same time, so there's a need for definitions.


It's the current fashion, indeed, in hardware. Theorists have many
another possibility to hand if it should ever go out of fashion.


Could you be specific as to the problem that you're experiencing?


That seems to be a rather limited way of saying "when increasing the
size of a signed integer, extend the sign bit". Nothing new there,
really.

Could you be more specific about what you're trying to achieve?
Quoting the entire history of the universe and hanging it onto the end
of your posting is all very well, but even that seems to lack the
necessary context.

moderated >> 2's complement usage in Perl

by Keith Thompson » Tue, 12 Apr 2005 09:08:33 GMT

"Liam" < XXXX@XXXXX.COM > writes:

Yes, I know what 2's complement is, but I still don't understand what
problem you're trying to solve.

You've said that

"ffbe8e should render as -16754, not 16760462"

but one example doesn't make a problem description.

Is the input a string? Why do you consider ffbe8e to represent a
negative value? Is fbe8e (5 hex digits) also negative? What about
00ffbe8e? How would you represent the value 16760462 as a hex number?

The hexadecimal value ffbe8e, stored in a 32-bit 2's-complement
(signed) integer, is a positive value, representable in decimal as
16760462 (the hexadecimal value can also be represented as 00ffbe8e to
show the leading zeros explicitly). The same value stored in a 24-bit
2's-complement integer is a negative value, -16754. If you
sign-extend ffbe8e to 32 bits, it becomes ffffbe8e; is that what you
want? What, if anything, determines whether you want a 24-bit or
32-bit result?

If you want to do sign-extension, you need to define the size of the
input and the size of the output. In other words, you're extending
the sign from where to where?

My guess is that you're looking for a function that takes a string
argument (consisting of hex digits) and returns a numeric value. Show
some examples of what you want the function to return for various
arguments. Include at least the following:

"fbe8e"
"ffbe8e"
"0ffbe8e"
"ffffbe8e"
"1be8e"
"1fbe8e"
"1fffbe8e"

If you're not looking for something that converts a string to a
number, please be more specific about what you do want.

Are you concerned about the way Perl handles hexadecimal literals in
Perl source code? If so, note that ffe8e is not a numeric literal;
0xffe8e is.

Once you've defined the problem, the solution should be quite simple.

--
Keith Thompson (The_Other_Keith) XXXX@XXXXX.COM < http://www.ghoti.net/ ~kst>
San Diego Supercomputer Center <*> < http://users.sdsc.edu/ ~kst>
We must do something. This is something. Therefore, we must do this.

moderated >> 2's complement usage in Perl

by Liam » Tue, 12 Apr 2005 21:23:22 GMT

Thanks to all for your time and consideration. Here is an example of
the solution that I was seeking:

open (BINFILE, "<000332") || die "Cant open: $!\n";
while(read(BINFILE, $data, 3)){
$data=hex(unpack 'H*',$data);
if ($data & 0x800000) {$data |= 0xff000000};
printf "%d \n", $data;
}
close (BINFILE) || die "Cant close: $!\n";

moderated >> 2's complement usage in Perl

by Yitzchak Scott-Thoennes » Wed, 13 Apr 2005 03:33:36 GMT


Ok, now by showing real code you have demonstrated that you aren't
talking about a string like "ffbe8e", but a 3-byte chunk of data like
"\xff\xbe\x8e".

But your solution is flawed. printf("%d") is what is forcing 2's
complement interpretation here, by casting to a signed integer at
the C level. Adding a simple

print "negative" if $data < 0;

will show that you aren't getting what you want in $data itself. This
will help some:

if ($data & 0x800000) { use integer; $data |= 0xff000000 }

use integer forces math and numeric bitwise operations to convert the
operands and the result to signed (2's complement) integers.

Even that won't work if perl is using 64-bit integers. Easiest way
to deal with that is probably:

if ($data & 0x800000) { $data -= 2**24 }

moderated >> 2's complement usage in Perl

by Ilmari Karonen » Fri, 22 Apr 2005 07:04:21 GMT

Liam < XXXX@XXXXX.COM > kirjoitti 12.04.2005:

Ahh... so this isn't really about hexadecimal numbers at all.

Besides the issues pointed out by Yitzchak Scott-Thoennes, all the
messing about with hex() and unpack('H*') is really not needed at all.
Here's how I might rewrite that loop:

open BINFILE, '<', $filename or die "Can't open $filename: $!\n";

while (read BINFILE, my $data, 3) { # read 24-bit big-endian value
my $int = unpack "N", "\0$data"; # parse as unsigned 32-bit
$int -= 1<<24 if $int & 1<<23; # make negative if sign bit set
print "$int\n"; # print in decimal
}

Another, slightly more compact way to write it would be:

while (read BINFILE, my $data, 3, 1) { # read 24-bit big-endian value
my $int = unpack "N", $data; # parse as unsigned 32-bit
$int -= ($int & 1<<23) << 1; # make negative if sign bit set
print "$int\n"; # print in decimal
}

This uses the offset argument of read() to prepend the null byte, and
also a different way of doing the sign extension. Either way works.

--
Ilmari Karonen
To reply by e-mail, please replace ".invalid" with ".net" in address.

Similar Threads

1. Question about 2's complement

Dear all:
I have to compare 2 values which is represented by 2 bytes as 0xffff
and 0x00fe in 2's complement system.
so the difference between them should be -1 - 254 =-255.
but before do such calculation, I have to translate 0xffff as -1.
Is there build-in function in perl for me to use, or should I transfer
it by hand?
below is the method I thought, but it really seems lousy.

my $tmp_value1="ffee";
if (hex $tmp_value1 & 0x8000)
{
	my $int=int $tmp_value1;
	$int -= 2**16;
	$tmp_value1=$int;
}
appreciate your help,
miloody

2. Perl function for negative integers using the 2's complement in hex? - Perl

3. how to do bit complement in perl

hi all,

i have a file in which there are 8 byte hex values one followed by
another. For example:
2A414364
00001DA9
01A3F9DD
3FFFF661
00EE6670
000011CF
2BC43FD0
3FEB0003
3F7FFF40

I need to check for the last bit in every data and if it being set,
then the next data's 24 bits have to be inverted(assuming last bit is
d31, starting from d26 to d7 needs to be inverted). For example:
1st data 0x2A414364 has last bit as '0' so the next word can be
retained as same.But, 00001DA9(2nd data), the last bit is '1' so the
next data  01A3F9DD will have to be printed as 3e5c061d. so, for the
upper set of data, the below data needs to be printed. how do i do bit
complement in hex using perl.

2a414364
00001da9
3e5c061d
000009a1
3f1199b0
000011cf
143bc010
3feb0003
00800080

regards,
bala

4. Complement of =~ - Perl

5. How does the complement work with transliteration ?

Hello
I was wondering how tr/abcd/1234/cs is supposed to work... I intend it
to mean- if its anything other than abcd replace with ... I am not
sure what the right way is.

Without the /c,  tr/abcd/1234/s does the expected, replaces each of a
b c and d found, with their corresponding replacement characters. But
in the /c case I notices that any character that was not one of abcd
was replaed with 4, the last character in the REPLACEMENTSTRING 1234.

I tried to look at documentation - they have just one example of
replacing all that dont fit the search with a space. If any of you
have examples of how you use this thing with /c, i'd love to see them.
Thanks
anita

6. gluCylinder Perl Usage

7. Perl memory usage debugging techniques

I have a search engine that can search in XML documents.  The search
engine is written in Perl, with some parts in C.

It needs inane amounts of memory, so much that the machine often
starts to thrash.

So now I'm trying to find a way to find out where the memory is used
and how to make it use less memory.  I have tried som things, but I
don't know what else to try.  There has got to be a systematic
approach which will lead to success somehow, but I haven't found it,
yet.

I started by writing a batch version that you start from the command
line, give it a query, and then it will process that query.  By
looking at the script, I can see all lexicals that are used and
examine their sizes.

My findings are as follows:

>From the beginning (before query processing starts) to the end (after
query processing) the Perl process grows from 19,068 by 71,964 to
91,032 kB.

After query processing, the lexicals in use are: parser (1 kB), parsed
query (0 kB), low-level interface layer (521 kB), intermediate query
representation (521 kB), another intermediate query representation
(10 kB), and the query result (4 kB).

I didn't count the lexicals that receive command line options, and
neither those for parsing the output of "ps -up $$", and also the
Log::Log4perl object is missing.

All other memory usage happened in lexicals in various methods that
have now gone out of scope.  The memory could also have been used
internally by DB_File or DBM::Deep, the above described run used
DBM::Deep.  I use those for storing the index created by the search
engine.  Another possibility, of course, is that the memory is used
by the C parts.

I used the total_size function from Devel::Size to find the memory
usage of the lexicals.  Since I don't grok what is going on, the
numbers might be misleading.  I used the `ps -up $$` construct to
find the size of the Perl process.

I have also taken the class that I suspected used the most memory, and
then changed the constructor and destructor to make an entry in a table
for each object created and each object destroyed.  Then, whenever an
object was created or destroyed, I printed the current statistics on
bytes ever allocated and bytes ever freed.  This tells me that
something like 9 MB of memory was ever freed during the lifetime of
the program; this is also not enough to explain the 71 MB used.

I intend to use Devel::Symdump to find the symbol table and to sum up
its memory usage using Devel::Size, as well.

Obviously, these approaches aren't sufficient for finding the
problem; can you teach me some technique that could help?  I have
already learned from a previous posting that Perl does not like to
return memory to the system, and often it does not want to reuse
memory allocated for another variable.  I have no idea how to find
unused bits of memory, nor how to find out why Perl didn't reuse
other memory, or how to make it reuse more.

tia,
Kai

----- End forwarded message -----

8. Perl Debugger usage with Tk events...