# Error Handling for negative real numbers

**URL:** <https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120>\
**Category:** Help\
**Created:** [June 15, 2020, 3:26pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120 "2020-06-15T15:26:47Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ELNS](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/elns/32/3338_2.png) [@ELNS](https://fortran-lang.discourse.group/u/ELNS)\
**Post date:** [June 15, 2020, 3:26pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/1 "2020-06-15T15:26:47Z")

</div>

Hi all  
How can we handle “Error: Raising a negative REAL at (1) to a REAL power is prohibited” in example below:  
(-8) \*\* (1.0 / 3.0)

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [June 15, 2020, 4:31pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/2 "2020-06-15T16:31:24Z")

</div>

Use complex numbers ?  
With real numbers, you can not compute (-8)^{1/2} =\> square root of a negative number  
Same (mathematical) problem with 1/3.

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [June 15, 2020, 5:37pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/3 "2020-06-15T17:37:19Z")

</div>

@ELNS  
See: [https://math.stackexchange.com/questions/317528/how-do-you-compute-negative-numbers-to-fractional-powers](https://math.stackexchange.com/questions/317528/how-do-you-compute-negative-numbers-to-fractional-powers)

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [June 15, 2020, 5:45pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/4 "2020-06-15T17:45:37Z")

</div>

@ELNS  
There is some subtle things there, more subtle than it seems 🤪 🥴:

- you can compute \sqrt[3]{-27}: it’s -3, because -3 \times (-3) \times (-3)=-27
- But you can not compute (-27)^{1/3}

In fact, the mathematical function \sqrt[3]{x} = x^{1/3} when x \gt 0.

As far as I know, there is no cubic root function in Fortran  
=\> probably an interesting exercise…

---

<div class="post-metadata">

**Author:** ![ELNS](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/elns/32/3338_2.png) [@ELNS](https://fortran-lang.discourse.group/u/ELNS)\
**Post date:** [June 15, 2020, 6:30pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/5 "2020-06-15T18:30:23Z")

</div>

Thank you so much for helping me 🙏 🙏

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [June 15, 2020, 7:00pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/6 "2020-06-15T19:00:22Z")

</div>

> [@ELNS](#):
>
> How can we handle “Error: Raising a negative REAL at (1) to a REAL power is prohibited” in example below:  
> (-8) \*\* (1.0 / 3.0)

I’m confused. Where is this prohibited? Not in Fortran, it’s not. You can do it but you won’t get a meaningful answer:

```fortran
$ cat test_exception1.f90 
program test_exception
  implicit none
  integer :: n
  real :: x, y
  do n = 1, 10
    call random_number(x) ! random number in [0, 1]
    x = x - 0.5 ! random number in [-0.5, 0.5]
    y = x**(1./3.)
    print *, 'x, y = ', x, y
  end do
end program test_exception
$ gfortran -Wall -std=f2018 test_exception1.f90 && ./a.out 
 x, y = 8.94961357E-02 0.447302580    
 x, y = 0.190010607 0.574900389    
 x, y = 0.334387779 0.694091618    
 x, y = 6.04379177E-03 0.182153061    
 x, y = -0.412383974 NaN
 x, y = 0.465656042 0.775095224    
 x, y = -0.412225127 NaN
 x, y = 0.237244248 0.619058788    
 x, y = -0.436005294 NaN
 x, y = -6.18785620E-02 NaN

```

This can happen in real-world applications–you need to work with real numbers and you can’t always predict that they’ll be positive. But you’re right, you should be able to handle it. Here’s how you can do it for this specific case:

```fortran
$ cat test_exception2.f90 
program test_exception
  use ieee_arithmetic, only: ieee_is_nan
  implicit none
  integer :: n
  real :: x, y
  do n = 1, 10
    call random_number(x) ! random number in [0, 1]
    x = x - 0.5 ! random number in [-0.5, 0.5]
    y = x**(1./3.)
    if (ieee_is_nan(y)) then ! catch exception
      print *, 'Exception caught in y = x**(1./3.), x, y = ', x, y
      ! handle exception here however you want
    else
      print *, 'x, y = ', x, y
    end if
  end do
end program test_exception
$ gfortran -Wall -std=f2018 test_exception2.f90 && ./a.out 
 x, y = 0.381638110 0.725354970    
 x, y = 1.73110366E-02 0.258686841    
 Exception caught in y = x**(1./3.), x, y = -0.201909781 NaN
 Exception caught in y = x**(1./3.), x, y = -0.197003841 NaN
 Exception caught in y = x**(1./3.), x, y = -0.303777575 NaN
 x, y = 0.129012465 0.505293727    
 Exception caught in y = x**(1./3.), x, y = -0.205134809 NaN
 x, y = 0.403641343 0.739035368    
 x, y = 0.304455400 0.672730684    
 x, y = 5.94465733E-02 0.390279382   

```

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [June 15, 2020, 7:33pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/7 "2020-06-15T19:33:03Z")

</div>

This is not a Fortran problem. But a mathematical one:  
Real exponents are mathematically an extension of integer exponents. If a is a real, x^a can be defined by e^{a \cdot ln(x)}, and therefore it is not defined if x \le 0, unless you work in \mathbb{C}.

See:

- [https://en.wikipedia.org/wiki/Exponentiation#Real\_exponents](https://en.wikipedia.org/wiki/Exponentiation#Real_exponents)
- [https://math.stackexchange.com/questions/448993/nth-roots-of-negative-numbers](https://math.stackexchange.com/questions/448993/nth-roots-of-negative-numbers)

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [June 15, 2020, 7:43pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/8 "2020-06-15T19:43:39Z")

</div>

Okay, I just enabled a plugin for that. Here’s an example of inline and block math:

```auto
Inline: $\sqrt{x^2 + y^2}$

```

Inline: \sqrt{x^2 + y^2}

```auto
Block:

$$
\sqrt{x^2 + y^2}
$$

```

Block:

\sqrt{x^2 + y^2}

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [June 15, 2020, 7:44pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/9 "2020-06-15T19:44:14Z")

</div>

> [@vmagnin](#):
>
> This is not a Fortran problem. But a mathematical one:

Perhaps, but I didn’t get that idea from the original post. 🙂

---

<div class="post-metadata">

**Author:** ![septc](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/septc/32/77_2.png) [@septc](https://fortran-lang.discourse.group/u/septc)\
**Post date:** [June 15, 2020, 8:19pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/10 "2020-06-15T20:19:13Z")

</div>

Using complex variables seems to work here…

```auto
program main
    use iso_fortran_env, only: dp => real64
    implicit none

    print *, cmplx( -8.0, 0.0 )**( 1.0 / 3.0 )
    print *, ( cmplx( -8.0, 0.0 )**( 1.0 / 3.0 ) )**3
    print *
    print *, cmplx( -8.0, -0.0 )**( 1.0 / 3.0 )
    print *, ( cmplx( -8.0, -0.0 )**( 1.0 / 3.0 ) )**3
    print *
    print *, cmplx( -8.0_dp, 0.0_dp, dp )**( 1.0_dp / 3.0_dp )
    print *, ( cmplx( -8.0_dp, 0.0_dp, dp )**( 1.0_dp / 3.0_dp ) )**3

    print *, cmplx( -8.0_dp, -0.0_dp, dp )**( 1.0_dp / 3.0_dp )
    print *, ( cmplx( -8.0_dp, -0.0_dp, dp )**( 1.0_dp / 3.0_dp ) )**3
end

```

Result (gfortran-9.3):

```auto
            (0.999999940,1.73205090)
      (-8.00000095,-1.148161914E-06)

           (0.999999940,-1.73205090)
       (-8.00000095,1.148161914E-06)

               (1.0000000000000000,1.7320508075688772)
        (-7.9999999999999991,6.02105053308414143E-016)

              (1.0000000000000000,-1.7320508075688772)
       (-7.9999999999999991,-6.02105053308414143E-016)

```

Interestingly, Python gives a complex result from (-8)\*\*(1.0 / 3.0) (w/o making -8 to complex),

```python
>>> (-8)**(1.0 / 3.0)
(1.0000000000000002+1.7320508075688772j)
>>> (-8.0 + 0.0j)**(1.0 / 3.0)
(1.0000000000000002+1.7320508075688772j)
>>> (-8.0 - 0.0j)**(1.0 / 3.0)
(1.0000000000000002-1.7320508075688772j)

```

while Julia refuses it and requires a complex argument (so similar to Fortran):

```auto
> (-8.0)^(1.0 / 3.0)
**ERROR:** DomainError with -8.0:
Exponentiation yielding a complex result requires a complex argument.
Replace x^y with (x+0im)^y, Complex(x)^y, or similar.

> (-8.0 + 0.0im)^(1.0 / 3.0)
1.0 + 1.7320508075688772im
> (-8.0 - 0.0im)^(1.0 / 3.0)
1.0 - 1.7320508075688772im

```

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [June 15, 2020, 8:37pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/11 "2020-06-15T20:37:05Z")

</div>

@milancurcic

> Perhaps, but I didn’t get that idea from the original post.

I agree with you, the question was:

> [@ELNS](#):
>
> How can we handle “Error:

so handling the exception is the exact answer.  
I was obsessed by the mathematical aspect…

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [June 15, 2020, 11:53pm UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/12 "2020-06-15T23:53:19Z")

</div>

Fortran 2018, 10.1.5.2.4 Evaluation of numeric intrinsic operations, paragraph 1:

> Raising a negative real value to a real power is prohibited.

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [June 16, 2020, 12:13am UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/13 "2020-06-16T00:13:02Z")

</div>

I had no idea! Is this new in F2018?

Does it mean that a standard-conforming compiler must check at run-time that such operation doesn’t occur, like in my example above? gfortran-9.2.0 doesn’t do this, even with the `-std=f2018` flag.

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [June 16, 2020, 12:29am UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/14 "2020-06-16T00:29:38Z")

</div>

No - it’s even in FORTRAN 66 (6.4):

> No factor may be evaluated that requires a negative valued primary to be raised to a real or double precision exponent.

The standard NEVER requires a “processor” to do run-time checks, and this isn’t a numbered syntax rule or constraint that requires the ability to diagnose.

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [June 16, 2020, 12:33am UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/15 "2020-06-16T00:33:58Z")

</div>

The thing to always keep in mind is that the Fortran standard describes the behavior of a standard-conforming program. If you color outside the lines, the standard does not specify the behavior. This gives a compiler great freedom to support extensions and behaviors such as giving you a NaN where the floating point model indicates is appropriate.

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [June 16, 2020, 1:07am UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/16 "2020-06-16T01:07:06Z")

</div>

Thank you, Steve, this is very interesting. I think I got stuck on the word “prohibited”. So, this statement:

> Raising a negative real value to a real power is prohibited.

can be interpreted as:

> The result of raising a negative real value to a real power is undefined.

Do you agree?

Second, consider this program:

```fortran
program schrodinger
  character(10) :: arg
  real :: x
  call get_command_argument(1, arg)
  read(arg, *) x
  print *, x, x**(1./3.)
end program schrodinger

```

Is this program standard-conforming?

Based on my interpretation of the quoted rule, my conclusion is that the program is standard-conforming if the user inputs a positive value, and not if the user inputs a negative value. Until then, it’s both at the same time. 🙂

I bet there is a flaw somewhere in my thought process here, but I can’t find it. What do you think?

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [June 16, 2020, 1:28am UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/17 "2020-06-16T01:28:22Z")

</div>

No, I don’t agree with your first statement. The standard makes a distinction between behaviors that are prohibited (in that if you do so, your program is non-conforming), and behaviors whose effect is “processor-dependent” (the program is conforming, but the standard does not tell you what happens.)

Here’s a real-world example where the standard changed wording but not behavior. In Fortran 2008, 9.5.4 said:

> A unit shall not be connected to more than one file at the same time, and a file shall not be connected to more than one unit at the same time.

Fortran 2018 changed that to (12.5.4):

> A unit shall not be connected to more than one file at the same time. … It is processor dependent whether a file can be connected to more than one unit at the same time.

What is the practical difference here? A program that opened a file on more than one unit was non-conforming in Fortran 2008, but in Fortran 2018 that behavior was conforming. Compilers didn’t have to change - some already allowed it, some didn’t - both conformed to the standard in this regard (because it is describing what the program may or may not do), but programs that did this were no longer deemed nonconforming. This mattered to some users.

Your program is non-conforming if a negative value is input. It’s not “both at the same time”. There are many behaviors prohibited by the standard (deallocating an object that is not allocated, for example) which are entirely based on program flow. Whether a program is standard-conforming requires you to consider the totality of it, both in source form and execution behavior. Compilers are required to have the capability of diagnosing certain source form issues (numbered syntax rules and constraints), but the lack of a complaint doesn’t paste a gold star on your program’s forehead.

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [June 16, 2020, 1:34am UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/18 "2020-06-16T01:34:42Z")

</div>

Okay, thank you for clarifying that, I think I understand now. I just learned something very important–you can’t determine standard-conformance of a program solely based on its source.

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [June 16, 2020, 3:39am UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/19 "2020-06-16T03:39:54Z")

</div>

That is a fascinating way to think about standards compliance. I did not realize that a program’s compliance could be based on its input. Perhaps that is what the standards developers intended, but not at all the way I would have initially thought about it.

This leads me to an interesting question. Is it possible to prove that a program is standards compliant for all possible inputs?

Also an interesting implication, it would be possible to write esoteric programs that were only standards compliant on the third Thursday of the 4th month of every fifth leap year or some such strange case.

---

<div class="post-metadata">

**Author:** ![gardhor](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/gardhor/32/88_2.png) [@gardhor](https://fortran-lang.discourse.group/u/gardhor)\
**Post date:** [June 16, 2020, 7:22am UTC](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120/20 "2020-06-16T07:22:37Z")

</div>

Hi,

This is a nice example how to catch exceptions in fortran.

Although, the question was about “Error Handling”, I think it is better to test if x is negative or positive or zero. It will be more clear about the “mathematical” aspect.

[Next page](https://fortran-lang.discourse.group/t/error-handling-for-negative-real-numbers/120.md?page=2)
