{"id":3043,"date":"2017-05-31T19:54:47","date_gmt":"2017-05-31T18:54:47","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=3043"},"modified":"2017-05-31T19:54:47","modified_gmt":"2017-05-31T18:54:47","slug":"fortran-nan-and-min-max","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=3043","title":{"rendered":"FORTRAN - NaN and min() max()"},"content":{"rendered":"<p>What happens if one put NaN into min() or max()? Will it return NaN or the other number? Is it deterministic or random?<br \/>\nSounds easy to test but its hard to implement. For example: How one get a quite-NaN number? A quite-NaN dosen't trigger debug traps, signaling-NaN do. There is no standard way in pre Fortran 2003! One have to google some nasty integer-float bit tricks. But with Fortran 2003 there is an intrinsic module ieee_arithmetic, which has the function ieee_value() which can return a quite-NaN. And one can test for Nan wich the function ieee_is_nan().<\/p>\n<p>Remeber, C++ provide this functionality with std::numeric_limits::quite_nan() in C++1998 or earlier. <\/p>\n<p>So the test ist quite simple. We put a number and NaN into min() and compare the result with our expected number. We do this for every combination and for min() and max(). The result for gfortran 6.3.2 32bit is: The returned number is alway not NaN, expect for the case where both parameter are NaN. Then, the function has no choice and returns NaN.<\/p>\n<p>Back to the implementation. We want an automatic test, to quick start the program on different hardware and software settings. With a nice console output what happens, and what happens wrong.<br \/>\nThere are two ways to do this. The easy one with lots of code duplication. And the right on, with only on test() function which get called for one test.<br \/>\nThe test() function gets a varliable a, b which we wanna test. x als the expected result. A procedure pointer to either min() or max() and a short string with the function name we wanna test. For example:<\/p>\n<p>call test(func, \"min\", 3.0, NAN, 3.0);<\/p>\n<p>But... one can not get a procedure pointer on a intrinsic function!?? And if you implement your own function, it has to be a subroutine!??<\/p>\n<p>Fortran is broken by design.<\/p>\n<p>This ends up in lot more code and paint than is has to. See my next post where I implement this test in C++. Without pain and only half of code size.<\/p>\n<p>Here is the 56line problem:<\/p>\n<pre><code>\r\nmodule test_m\r\n  use, intrinsic :: IEEE_ARITHMETIC\r\n  contains\r\n  \r\n  subroutine test(func, funcname, a, b, x) \r\n    implicit none\r\n    procedure(), pointer :: func => null()  \r\n    real, intent(in) :: a, b, x\r\n    character(len=*), intent(in) :: funcname\r\n    real :: res\r\n    \r\n    call func(a,b,res)\r\n    write(*,*) funcname, \"(\",a, \",\", b, \") =\", res\r\n    \r\n    if(ieee_is_nan(x)) then\r\n      if(.not. ieee_is_nan(res)) then\r\n        write(*,*) \"But sould be\", x\r\n      endif\r\n    else if(res \/= x) then\r\n      write(*,*) \"But should be\", x\r\n    endif    \r\n  end subroutine\r\n\r\n  subroutine mymin(a,b, x)\r\n    implicit none\r\n    real, intent(in) :: a, b\r\n    real, intent(out) :: x\r\n    x = min(a,b)\r\n  end subroutine\r\n  \r\n  subroutine mymax(a,b, x)\r\n    implicit none\r\n    real, intent(in) :: a, b\r\n    real, intent(out) :: x\r\n    x = max(a,b)\r\n  end subroutine\r\nend module\r\n\r\nprogram fmin    \r\n  use test_m\r\n  implicit none\r\n  real :: NAN\r\n  procedure(), pointer :: func => null()\r\n  \r\n  NAN = IEEE_VALUE(NAN, IEEE_QUIET_NAN)\r\n\r\n  func => mymin  \r\n  call test(func, \"min\", -3.0, NAN, -3.0)\r\n  call test(func, \"min\", NAN, -3.0, -3.0)\r\n  call test(func, \"min\", NAN, NAN,  NAN)\r\n\r\n  func => mymax  \r\n  call test(func, \"max\", -3.0, NAN, -3.0)\r\n  call test(func, \"max\", NAN, -3.0, -3.0)\r\n  call test(func, \"max\", NAN, NAN,  NAN)\r\nend program\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>What happens if one put NaN into min() or max()? Will it return NaN or the other number? Is it deterministic or random? Sounds easy to test but its hard to implement. For example: How one get a quite-NaN number? A quite-NaN dosen't trigger debug traps, signaling-NaN do. There is no standard way in pre [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[30],"class_list":["post-3043","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-fortran"],"_links":{"self":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3043","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3043"}],"version-history":[{"count":1,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3043\/revisions"}],"predecessor-version":[{"id":3044,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3043\/revisions\/3044"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3043"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3043"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}