Absolute value of signed 32-bit random integer

  • Thread starter John B. Matthews
  • Start date
A

Arne Vajhøj

Marcin said:
We differ in the definition of correctness then. Relying on overflow
may be convenient for most, but apps that need to be mathematically
correct (I thought you were speaking of mathematical correctness) are
NOT relying on overflow, as this is clearly not correct.

If somebody read the JLS, JVM spec and Java docs for the API and
writes code that according to those specs does what it is supposed
to do, then the code is correct.

There not A and B citizens in the spec. The spec say X, but it is still
not correct to use that feature.

I do not like code that relies on overflow behavior, but that is from
a readability/maintenance perspective.

Correct code is not necessarily good code.
Generics did not break anything only because a lot of work had been
applied to ensure that (like aforementioned collections addition).
From the point of view of language it was non trivial addition which
Java designers/maintainers never really overtook


Still, these have been serious changes of language/compiler which
never took place in Java world.

The JCP process is moving at a lot slower pace than MS. C# are
getting new features at a much higher rate than Java. I will
not argue that.

But note that when it comes to programming languages then bigger
is not always better.

Compare the usage of Cobol and C with that of PL/I and Ada.

Arne
 
T

Tom Anderson

It's the relevant, useful idea of "correct" for APIs.

It's certainly an essential concept - programs must be written according
to what the routine does, not what it would do in some utopian dreamland.

But i wouldn't dignify it with the word 'correct'.
You want "correct" to mean "what I want the spec to be", but the API writer
cannot satisfy everyone on that count.

This is mendacious. In this case, it's not just me that want's the spec to
be like that, it's everyone except a few scattered speed-freaks, and the
library writer could easily have satisfied everyone.
If the particular method doesn't do what you want to be "correct", use a
different method.

Will do.

tom
 
T

Tom Anderson

Tom said:
Tom Anderson wrote:
50 PM, Peter Duniho wrote:
Getting the _actual_ absolute value of some number will never correctly
return a negative result. So, either Math.abs() isn't really a function
returning the absolute value of the input, or it's not behaving
correctly.

By that argument, most of the operations in Java or almost every other
programming language are also not mathematically correct.

You're quite right. They aren't. We've mostly put up with it because we
don't know any better and we're terrified of the performance cost of
doing it right [1], but they're still wrong.

If they work as documented, then they are correct.

That's a pathetic, narrow-minded idea of 'correct'. We can do better.

/**
* Returns 2.
*/
public int getFoobar() {
return 2;
}

is correct. And it is verifiable that it is correct.

But let us say that Lew wrote that code, then you may consider:

public int getFoobar() {
return 1;
}

better and I may consider:

public int getFoobar() {
return 3;
}

better.

But it has nothing to do with correctness of the code. It is
a discussion about what behavior is "best".

It is not verifiable which one is best. In fact there may not be "a"
best, because it is perfectly valid that Lew, you and me have different
priorities that result in different conclusions regarding what is best.

Again, mendacious. The difference between purporting that
abs(Integer.MIN_VALUE) is Integer.MIN_VALUE and refusing to give an answer
for it is not simply a matter of taste. The latter really is better.

In general, there are certainly cases where the are multipel valid
opinions on what the right behaviour is. This is not one of them.

tom
 
T

Tom Anderson

In general, there are certainly cases where the are multipel valid
opinions on what the right behaviour is.

But not where there are multiple valid spellings of 'multiple'. Apologies.

tom
 
A

Arved Sandstrom

Lew said:
It's the relevant, useful idea of "correct" for APIs.

You want "correct" to mean "what I want the spec to be", but the API
writer cannot satisfy everyone on that count.

If the particular method doesn't do what you want to be "correct", use a
different method.
Or even better, use a more appropriate data type. A finite-precision
computer science integer data type cannot represent a mathematical
integer, so why quibble about the fact that methods that work with these
limited data types have edge cases?

AHS
 
J

John B. Matthews

Peter Duniho said:
lol...and here I was figuring I'd mention the 6502 as another
example. Now, _that's_ old.

Reminiscing, I recall that the 6502 has an overflow flag, V:

<http://www.6502.org/tutorials/vflag.html>

A conditional branch on clear, BVC, may be seen in the definition of the
Forth word LESS, '<':

<http://home.roadrunner.com/~jbmatthews/a2/prosource.html>

Thanks to all for a spirited discussion. I am occasionally afforded the
opportunity to review others' code, and a tool like FindBugs can be very
useful. Readers may enjoy "A Comparison of Bug Finding Tools for Java"
that examnes Bandera, ESC/Java 2, FindBugs, JLint and PMD:

<http://www.cs.umd.edu/~jfoster/papers/issre04.pdf>
 
A

Arne Vajhøj

Arved said:
Or even better, use a more appropriate data type. A finite-precision
computer science integer data type cannot represent a mathematical
integer, so why quibble about the fact that methods that work with these
limited data types have edge cases?

And java.math.BigInteger has been in Java since version 1.1.

Arne
 
A

Arne Vajhøj

Patricia said:
The integer cases of Math.abs issue could be resolved, without upgrade
problems, by adding Math.checkedAbs defined to throw
IllegalArgumentException if the input's absolute value cannot be
represented in the input type.

Math.checkedAbs or StrictIntMath.abs - it is not that difficult
to add it in a non-breaking way.

Arne
 
A

Arne Vajhøj

Arne said:
It runs Java and systems are still used in many places.

And BTW, systems with that CPU were sold until 2007.

It was research in new CPU's that were abandoned in 2001 and there are
a lead time from research to shipping systems.

Arne
 
M

Marcin Rzeźnicki

If somebody read the JLS, JVM spec and Java docs for the API and
writes code that according to those specs does what it is supposed
to do, then the code is correct.

There not A and B citizens in the spec. The spec say X, but it is still
not correct to use that feature.

I do not like code that relies on overflow behavior, but that is from
a readability/maintenance perspective.

Correct code is not necessarily good code.

Right, it is correct according to Java, which I am not questioning
here. But these apps do not produce correct mathematical results and
that's the primary reason why semantics like these we've been
discussing should be added to the language - to help apps that need to
adhere to mathematical correctness. Everything else may as well be
left as it is.

The JCP process is moving at a lot slower pace than MS. C# are
getting new features at a much higher rate than Java. I will
not argue that.

But note that when it comes to programming languages then bigger
is not always better.

Compare the usage of Cobol and C with that of PL/I and Ada.

Of course, but I think that Java has been lagging behind - there is a
difference between moving at slow pace and freezing language
evolution.
 
J

John B. Matthews

Peter Duniho said:
John said:
[...]
lol...and here I was figuring I'd mention the 6502 as another
example. Now, _that's_ old.

Reminiscing, I recall that the 6502 has an overflow flag, V:

<http://www.6502.org/tutorials/vflag.html>

"an" overflow flag. I was assuming Arne's challenge was with respect
to there being two different overflow bits.

Ah, I see what you mean. Arne quoted markspace, "All CPUs have two
overflow bits, one for signed math ... and one for unsigned math." I
should have clarified that the 6502 overflow (V) bit signals signed
overflow, while the carry (C) bit signals unsigned overflow. As a
result, I think the 6502 fails as a counter-example.

As as aside, I had to dig for an arithmetic example. Another usage
follows a BIT instruction, which effectively conditions both C and V in
a single instruction.

For those interested in other languages, I might add that an explicit
attempt in Ada fails at compile-time:

K : Integer := abs(Integer'First);

A more devious approach compiles and produces the same result as Java.
It fails at run-time only if overflow checking is enabled during
compilation:

K : Integer := abs(Integer'First + Integer'Value("0"));

My error was not just misusing abs() but doggedly pursuing that pesky
sign bit when a better solution was at hand.
 
J

John B. Matthews

Peter Duniho said:
John said:
Peter Duniho said:
John B. Matthews wrote:
[...]
lol...and here I was figuring I'd mention the 6502 as another
example. Now, _that's_ old.
Reminiscing, I recall that the 6502 has an overflow flag, V:

<http://www.6502.org/tutorials/vflag.html>
"an" overflow flag. I was assuming Arne's challenge was with
respect to there being two different overflow bits.

Ah, I see what you mean. Arne quoted markspace, "All CPUs have two
overflow bits, one for signed math ... and one for unsigned math."
I should have clarified that the 6502 overflow (V) bit signals
signed overflow, while the carry (C) bit signals unsigned overflow.
As a result, I think the 6502 fails as a counter-example.

Yes, maybe. It depends on what "markspace" meant by "overflow bits".

I was hoping that by mentioning such an old, simple CPU that has only
one register flag described as an "overflow flag", he would take the
opportunity to clarify. The fact is, the "carry flag" isn't strictly
speaking an "overflow flag" (or at least, I wouldn't call it one, as
it is set when subtraction performed remains within the unsigned
range 0-255, not an overflow condition), though it does provide
overflow information.

Indeed, one clears the C bit (CLC) before adding and sets it (SEC)
before subtracting. More than a few references simply ignore the role of
V in these instructions, as signed arithmetic is often relegated to
library code. C and V each provide a quantum of information about
overflow in the general sense I took from markspace. More details here:

<http://www.atariarchives.org/2bml/chapter_10.php>
Maybe though that's actually what "markspace" meant, in which case
the 6502 isn't a counter-example. Or maybe he had something very
specific in mind in describing an "unsigned overflow flag". In which
case, it is.

I can't say for sure. I'm not him. :) In the end, it's a semantic
question, which I know how much some love to chase down the rat hole
but maybe not "markspace" so much. :) But I figured that given how
_unimportant_ the presence of both signed and unsigned overflow flags
on the CPU is to the question of whether it would be practical for
Java to support an exception on overflow, we could afford the
possible diversion on this particular side-topic. :)

Yes, designers usually conclude that the cost of overflow checking
outweighs the benefit, although I can see the appeal of an optional
check. A counter-example to markspace's generalization would make the
cost yet higher. For example, this popular, standard-compliant Ada
compiler defaults to no overflow checking, and the flag is ignored on
some supported platforms:

<http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gnat_ugn_unw/
Switches-for-gcc.html#Switches-for-gcc>

Ob Java on 6502: <http://sourceforge.net/projects/vm02/>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top