Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #37935 > unrolled thread

Can Java 8 do exact arithmetic as in C#

Started bybursejan@gmail.com
First post2018-01-08 04:17 -0800
Last post2018-01-08 17:53 -0800
Articles 9 — 5 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  Can Java 8 do exact arithmetic as in C# bursejan@gmail.com - 2018-01-08 04:17 -0800
    Re: Can Java 8 do exact arithmetic as in C# j4n bur53 <janburse@fastmail.fm> - 2018-01-08 13:21 +0100
      Re: Can Java 8 do exact arithmetic as in C# Eric Sosman <esosman@comcast-dot-net.invalid> - 2018-01-08 08:42 -0500
        Re: Can Java 8 do exact arithmetic as in C# j4n bur53 <janburse@fastmail.fm> - 2018-01-08 21:11 +0100
          Re: Can Java 8 do exact arithmetic as in C# bursejan@gmail.com - 2018-01-08 18:08 -0800
            Re: Can Java 8 do exact arithmetic as in C# bursejan@gmail.com - 2018-01-08 18:22 -0800
            Re: Can Java 8 do exact arithmetic as in C# v_borchert@despammed.com (Volker Borchert) - 2018-01-09 19:48 +0000
    Re: Can Java 8 do exact arithmetic as in C# Arne Vajhøj <arne@vajhoej.dk> - 2018-01-08 20:04 -0500
      Re: Can Java 8 do exact arithmetic as in C# bursejan@gmail.com - 2018-01-08 17:53 -0800

#37935 — Can Java 8 do exact arithmetic as in C#

Frombursejan@gmail.com
Date2018-01-08 04:17 -0800
SubjectCan Java 8 do exact arithmetic as in C#
Message-ID<0ef8b3c0-e45c-4624-a8b8-2bdc67135380@googlegroups.com>
Java 8 has a nice feature, maybe this
isn't known very well. But there are

a couple of new operations in Math:

    /**
     * Returns the sum of its arguments,
     * throwing an exception if the result overflows an {@code int}.
     *
     * @param x the first value
     * @param y the second value
     * @return the result
     * @throws ArithmeticException if the result overflows an int
     * @since 1.8
     */
    public static int addExact(int x, int y);

    /**
     * Returns the sum of its arguments,
     * throwing an exception if the result overflows a {@code long}.
     *
     * @param x the first value
     * @param y the second value
     * @return the result
     * @throws ArithmeticException if the result overflows a long
     * @since 1.8
     */
    public static long addExact(long x, long y);

Etc..

------------ Arne wrote ---------------


	Arne Vajhøj 	
02:06 (vor 11 Stunden)
Nachricht auf Deutsch übersetzen  
On 1/5/2018 2:59 PM, Daniele Futtorovic wrote:
- zitierten Text einblenden -
I like C# with the check enabled.

using System;

namespace E
{
     public class Program
     {
         private static void Avg(int a, int b)
         {
             Console.WriteLine("Average of {0} and {1} is {2}", a, b, (a
+ b) / 2);
         }
         public static void Main(string[] args)
         {
             Avg(123, 456);
             Avg(int.MaxValue, int.MaxValue);
             Console.ReadKey();
         }
     }
}

What is best:

Average of 123 and 456 is 289
Average of 2147483647 and 2147483647 is -1

or:

Average of 123 and 456 is 289
System.OverflowException: Arithmetic operation resulted in an overflow.

?

If one really need the integer overflow to work then it is actually
still possible by making it explicit.

(I had big problems coming up with an example where it make sense
to overflow, but ...)

using System;
using System.Text;

namespace E
{
     public class Program
     {
         private static int[] Encrypt(int[] a, int k)
         {
             int[] res = new int[a.Length];
             for(int i = 0; i < res.Length; i++)
             {
                 unchecked
                 {
                     res[i] = a[i] + k;
                 }
             }
             return res;
         }
         private static int[] Decrypt(int[] a, int k)
         {
             return Encrypt(a, -k);
         }
         private const int KEY = 123456789;
         public static void Main(string[] args)
         {
             int[] a1 = { int.MinValue, -1, 0, 1, int.MaxValue };
             int[] a2 = Encrypt(a1, KEY);
             int[] a3 = Decrypt(a2, KEY);
             for(int i = 0; i < a1.Length; i++)
             {
                 Console.WriteLine("{0} -> {1} -> {2}", a1[i], a2[i],
a3[i]);
             }
             Console.ReadKey();
         }
     }
}

works fine even with the check enabled due to the:

unchecked { }

block.

I think this is the right way. Check by default and have a way
to disable the check for specific code sections where it is
needed.

Arne 

[toc] | [next] | [standalone]


#37936

Fromj4n bur53 <janburse@fastmail.fm>
Date2018-01-08 13:21 +0100
Message-ID<p2vnnj$cqa$1@news.albasani.net>
In reply to#37935
The source code is available, its a pure Java
implementation, no native code. For example addExact
is implemented as follows:

     /**
      * Returns the sum of its arguments,
      * throwing an exception if the result overflows an {@code int}.
      *
      * @param x the first value
      * @param y the second value
      * @return the result
      * @throws ArithmeticException if the result overflows an int
      * @since 1.8
      */
     public static int addExact(int x, int y) {
         int r = x + y;
         // HD 2-12 Overflow iff both arguments
         // have the opposite sign of the result
         if (((x ^ r) & (y ^ r)) < 0) {
             throw new ArithmeticException("integer overflow");
         }
         return r;
     }

HD 2-12 probably means Handbook of ... (who knows?)
chapter 2 section 12.

bursejan@gmail.com schrieb:
> Java 8 has a nice feature, maybe this
> isn't known very well. But there are
> 
> a couple of new operations in Math:
> 
>      /**
>       * Returns the sum of its arguments,
>       * throwing an exception if the result overflows an {@code int}.
>       *
>       * @param x the first value
>       * @param y the second value
>       * @return the result
>       * @throws ArithmeticException if the result overflows an int
>       * @since 1.8
>       */
>      public static int addExact(int x, int y);
> 
>      /**
>       * Returns the sum of its arguments,
>       * throwing an exception if the result overflows a {@code long}.
>       *
>       * @param x the first value
>       * @param y the second value
>       * @return the result
>       * @throws ArithmeticException if the result overflows a long
>       * @since 1.8
>       */
>      public static long addExact(long x, long y);
> 
> Etc..
> 
> ------------ Arne wrote ---------------
> 
> 
> 	Arne Vajhøj 	
> 02:06 (vor 11 Stunden)
> Nachricht auf Deutsch übersetzen
> On 1/5/2018 2:59 PM, Daniele Futtorovic wrote:
> - zitierten Text einblenden -
> I like C# with the check enabled.
> 
> using System;
> 
> namespace E
> {
>       public class Program
>       {
>           private static void Avg(int a, int b)
>           {
>               Console.WriteLine("Average of {0} and {1} is {2}", a, b, (a
> + b) / 2);
>           }
>           public static void Main(string[] args)
>           {
>               Avg(123, 456);
>               Avg(int.MaxValue, int.MaxValue);
>               Console.ReadKey();
>           }
>       }
> }
> 
> What is best:
> 
> Average of 123 and 456 is 289
> Average of 2147483647 and 2147483647 is -1
> 
> or:
> 
> Average of 123 and 456 is 289
> System.OverflowException: Arithmetic operation resulted in an overflow.
> 
> ?
> 
> If one really need the integer overflow to work then it is actually
> still possible by making it explicit.
> 
> (I had big problems coming up with an example where it make sense
> to overflow, but ...)
> 
> using System;
> using System.Text;
> 
> namespace E
> {
>       public class Program
>       {
>           private static int[] Encrypt(int[] a, int k)
>           {
>               int[] res = new int[a.Length];
>               for(int i = 0; i < res.Length; i++)
>               {
>                   unchecked
>                   {
>                       res[i] = a[i] + k;
>                   }
>               }
>               return res;
>           }
>           private static int[] Decrypt(int[] a, int k)
>           {
>               return Encrypt(a, -k);
>           }
>           private const int KEY = 123456789;
>           public static void Main(string[] args)
>           {
>               int[] a1 = { int.MinValue, -1, 0, 1, int.MaxValue };
>               int[] a2 = Encrypt(a1, KEY);
>               int[] a3 = Decrypt(a2, KEY);
>               for(int i = 0; i < a1.Length; i++)
>               {
>                   Console.WriteLine("{0} -> {1} -> {2}", a1[i], a2[i],
> a3[i]);
>               }
>               Console.ReadKey();
>           }
>       }
> }
> 
> works fine even with the check enabled due to the:
> 
> unchecked { }
> 
> block.
> 
> I think this is the right way. Check by default and have a way
> to disable the check for specific code sections where it is
> needed.
> 
> Arne
> 

[toc] | [prev] | [next] | [standalone]


#37938

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2018-01-08 08:42 -0500
Message-ID<p2vsgr$2f1$1@dont-email.me>
In reply to#37936
On 1/8/2018 7:21 AM, j4n bur53 wrote:
> The source code is available, its a pure Java
> implementation, no native code. For example addExact
> is implemented as follows:
> 
>      /**
>       * Returns the sum of its arguments,
>       * throwing an exception if the result overflows an {@code int}.
>       *
>       * @param x the first value
>       * @param y the second value
>       * @return the result
>       * @throws ArithmeticException if the result overflows an int
>       * @since 1.8
>       */
>      public static int addExact(int x, int y) {
>          int r = x + y;
>          // HD 2-12 Overflow iff both arguments
>          // have the opposite sign of the result
>          if (((x ^ r) & (y ^ r)) < 0) {
>              throw new ArithmeticException("integer overflow");
>          }
>          return r;
>      }
> 
> HD 2-12 probably means Handbook of ... (who knows?)
> chapter 2 section 12.

https://en.wikipedia.org/wiki/Hacker's_Delight

... would be my guess.

-- 
esosman@comcast-dot-net.invalid
Eleven hundred eight days to go.

[toc] | [prev] | [next] | [standalone]


#37943

Fromj4n bur53 <janburse@fastmail.fm>
Date2018-01-08 21:11 +0100
Message-ID<p30j91$cvc$2@news.albasani.net>
In reply to#37938
Yes indeed, thank you very much.

2–13 Overflow Detection
http://www.hackersdelight.org/basics2.pdf

Eric Sosman schrieb:
> On 1/8/2018 7:21 AM, j4n bur53 wrote:
>> The source code is available, its a pure Java
>> implementation, no native code. For example addExact
>> is implemented as follows:
>>
>>      /**
>>       * Returns the sum of its arguments,
>>       * throwing an exception if the result overflows an {@code int}.
>>       *
>>       * @param x the first value
>>       * @param y the second value
>>       * @return the result
>>       * @throws ArithmeticException if the result overflows an int
>>       * @since 1.8
>>       */
>>      public static int addExact(int x, int y) {
>>          int r = x + y;
>>          // HD 2-12 Overflow iff both arguments
>>          // have the opposite sign of the result
>>          if (((x ^ r) & (y ^ r)) < 0) {
>>              throw new ArithmeticException("integer overflow");
>>          }
>>          return r;
>>      }
>>
>> HD 2-12 probably means Handbook of ... (who knows?)
>> chapter 2 section 12.
> 
> https://en.wikipedia.org/wiki/Hacker's_Delight
> 
> ... would be my guess.
> 

[toc] | [prev] | [next] | [standalone]


#37949

Frombursejan@gmail.com
Date2018-01-08 18:08 -0800
Message-ID<3db83943-14d9-4589-a535-59ccf4b826d3@googlegroups.com>
In reply to#37943
On 64-bit CPU, the following shouldn't be that
costly and is an alternative to the Java code:

    int x;
    int y;
    int z;
    long h = (long)x + (long)y;
    if (h < Integer.MIN_VALUE || Integer.MAX_VALUE < h) {
        /* overflow situation */
    } else {
        /* normal situation */
        z = (int)h;
    }
 
But if you don't fear working with value objects,
you could also promote to BigInteger, the long based 

constructor is handy here, when overflowing. And maybe 
also normalize back from this type to Integer.

Am Montag, 8. Januar 2018 21:11:30 UTC+1 schrieb burs...@gmail.com:
> Yes indeed, thank you very much.
> 
> 2–13 Overflow Detection
> http://www.hackersdelight.org/basics2.pdf
> 
> Eric Sosman schrieb:
> > On 1/8/2018 7:21 AM, j4n bur53 wrote:
> >> The source code is available, its a pure Java
> >> implementation, no native code. For example addExact
> >> is implemented as follows:
> >>
> >>      /**
> >>       * Returns the sum of its arguments,
> >>       * throwing an exception if the result overflows an {@code int}.
> >>       *
> >>       * @param x the first value
> >>       * @param y the second value
> >>       * @return the result
> >>       * @throws ArithmeticException if the result overflows an int
> >>       * @since 1.8
> >>       */
> >>      public static int addExact(int x, int y) {
> >>          int r = x + y;
> >>          // HD 2-12 Overflow iff both arguments
> >>          // have the opposite sign of the result
> >>          if (((x ^ r) & (y ^ r)) < 0) {
> >>              throw new ArithmeticException("integer overflow");
> >>          }
> >>          return r;
> >>      }
> >>
> >> HD 2-12 probably means Handbook of ... (who knows?)
> >> chapter 2 section 12.
> > 
> > https://en.wikipedia.org/wiki/Hacker's_Delight
> > 
> > ... would be my guess.
> >

[toc] | [prev] | [next] | [standalone]


#37950

Frombursejan@gmail.com
Date2018-01-08 18:22 -0800
Message-ID<b5804bad-be4b-4278-b851-f7041e49ba59@googlegroups.com>
In reply to#37949
Here is the code of such an 
Arithmetic Logic Unit (ALU):
https://github.com/jburse/jekejeke-devel/blob/master/jekrun/headless/jekpro/reference/arithmetic/EvaluableElem.java

And here is a variant of the same ALU 
with decimals that have a given precision. 
Like the MATLAB VPA, one can choose 
the requested number of digits:
https://github.com/jburse/jekejeke-devel/blob/master/jekmin/headless/jekmin/frequent/decimal/SpecialArith.java

The later is quite fun, here is an example:

Jekejeke Prolog 2, Runtime Library 1.2.5
(c) 1985-2017, XLOG Technologies GmbH, Switzerland

?- use_module(library(decimal/multi)).
% 7 consults and 0 unloads in 272 ms.
Yes

?- X is pi.
X = 3.141592653589793

?- X is mp(pi,30).
X = 0d3.14159265358979323846264338327

?- X is mp(pi,100).
X = 0d3.14159265358979323846264338327
9502884197169399375105820974944592307
816406286208998628034825342117070

Etc...

With BigDecimal there is quite large exponent 
available, but when using a fixed number of digits 
problems remain the same. Its not really an 
overflow, but a rounding where information is lost. 

Thats why there is the topic of numerics.

Am Dienstag, 9. Januar 2018 03:08:29 UTC+1 schrieb burs...@gmail.com:
> On 64-bit CPU, the following shouldn't be that
> costly and is an alternative to the Java code:
> 
>     int x;
>     int y;
>     int z;
>     long h = (long)x + (long)y;
>     if (h < Integer.MIN_VALUE || Integer.MAX_VALUE < h) {
>         /* overflow situation */
>     } else {
>         /* normal situation */
>         z = (int)h;
>     }
>  
> But if you don't fear working with value objects,
> you could also promote to BigInteger, the long based 
> 
> constructor is handy here, when overflowing. And maybe 
> also normalize back from this type to Integer.
> 
> Am Montag, 8. Januar 2018 21:11:30 UTC+1 schrieb burs...@gmail.com:
> > Yes indeed, thank you very much.
> > 
> > 2–13 Overflow Detection
> > http://www.hackersdelight.org/basics2.pdf
> > 
> > Eric Sosman schrieb:
> > > On 1/8/2018 7:21 AM, j4n bur53 wrote:
> > >> The source code is available, its a pure Java
> > >> implementation, no native code. For example addExact
> > >> is implemented as follows:
> > >>
> > >>      /**
> > >>       * Returns the sum of its arguments,
> > >>       * throwing an exception if the result overflows an {@code int}.
> > >>       *
> > >>       * @param x the first value
> > >>       * @param y the second value
> > >>       * @return the result
> > >>       * @throws ArithmeticException if the result overflows an int
> > >>       * @since 1.8
> > >>       */
> > >>      public static int addExact(int x, int y) {
> > >>          int r = x + y;
> > >>          // HD 2-12 Overflow iff both arguments
> > >>          // have the opposite sign of the result
> > >>          if (((x ^ r) & (y ^ r)) < 0) {
> > >>              throw new ArithmeticException("integer overflow");
> > >>          }
> > >>          return r;
> > >>      }
> > >>
> > >> HD 2-12 probably means Handbook of ... (who knows?)
> > >> chapter 2 section 12.
> > > 
> > > https://en.wikipedia.org/wiki/Hacker's_Delight
> > > 
> > > ... would be my guess.
> > >

[toc] | [prev] | [next] | [standalone]


#37951

Fromv_borchert@despammed.com (Volker Borchert)
Date2018-01-09 19:48 +0000
Message-ID<p336a8$5il$1@Gaia.teknon.de>
In reply to#37949
bursejan@gmail.com wrote:
> On 64-bit CPU, the following shouldn't be that
> costly

Might depend on the actual CPU.

> and is an alternative to the Java code:
> 
>     int x;
>     int y;
>     int z;
>     long h = (long)x + (long)y;
>     if (h < Integer.MIN_VALUE || Integer.MAX_VALUE < h) {
>         /* overflow situation */
>     } else {
>         /* normal situation */
>         z = (int)h;
>     }

You might want to use non-circuit OR here to reduce the number
of conditional branches to predict.


-- 

"I'm a doctor, not a mechanic." Dr Leonard McCoy <mccoy@ncc1701.starfleet.fed>
"I'm a mechanic, not a doctor." Volker Borchert  <v_borchert@despammed.com>

[toc] | [prev] | [next] | [standalone]


#37944

FromArne Vajhøj <arne@vajhoej.dk>
Date2018-01-08 20:04 -0500
Message-ID<p314fm$1lag$1@gioia.aioe.org>
In reply to#37935
On 1/8/2018 7:17 AM, bursejan@gmail.com wrote:
> Java 8 has a nice feature, maybe this
> isn't known very well. But there are
> 
> a couple of new operations in Math:
> 
>      /**
>       * Returns the sum of its arguments,
>       * throwing an exception if the result overflows an {@code int}.
>       *
>       * @param x the first value
>       * @param y the second value
>       * @return the result
>       * @throws ArithmeticException if the result overflows an int
>       * @since 1.8
>       */
>      public static int addExact(int x, int y);
> 
>      /**
>       * Returns the sum of its arguments,
>       * throwing an exception if the result overflows a {@code long}.
>       *
>       * @param x the first value
>       * @param y the second value
>       * @return the result
>       * @throws ArithmeticException if the result overflows a long
>       * @since 1.8
>       */
>      public static long addExact(long x, long y);

Nice.

But probably of limited value.

The programmers calling these methods do so because
they are aware of the risk of overflow.

If these methods did not exist they would still be
aware and (hopefully) do something else to handle
the problem.

The problem is the programmers not aware of the
risk of overflow.

And these methods does not help them.

Arne

[toc] | [prev] | [next] | [standalone]


#37946

Frombursejan@gmail.com
Date2018-01-08 17:53 -0800
Message-ID<2dbb29f7-2a7b-47bd-8865-79c62aa7982f@googlegroups.com>
In reply to#37944
I think Oracle offers courses for this
situation, for about 1500 $ à week, intensive 

with a certificate. They gradually start with
easy steps such as switching on and off the 

computer, and then proceeds to fundamental 
questions where is front and back of the mouse.

I can only recommend, here is a demo video:
https://www.youtube.com/watch?v=dQw4w9WgXcQ

Am Dienstag, 9. Januar 2018 02:05:14 UTC+1 schrieb Arne Vajhøj:
> Nice.
> 
> But probably of limited value.
> 
> The programmers calling these methods do so because
> they are aware of the risk of overflow.
> 
> If these methods did not exist they would still be
> aware and (hopefully) do something else to handle
> the problem.
> 
> The problem is the programmers not aware of the
> risk of overflow.
> 
> And these methods does not help them.
> 
> Arne

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web