• Subnormal anomaly

    From Thomas Schnurrenberger@21:1/5 to All on Thu Oct 13 14:42:37 2022
    The following program gives an unexpected result when compiled and
    executed with gfortran on Windows:

    program test
    !
    use :: iso_fortran_env
    !
    implicit none
    !
    real(real64), parameter :: SUB1 = real(z'1', real64)
    real(real64), parameter :: SUB2 = real(z'2', real64)
    !
    character(len=1000) :: buff
    real(real64) :: got
    !
    ! Inexact representation of the smallest subnormal number:
    buff = '5e-324'
    read (buff, *) got
    print *, 'Expected:', SUB1, ', got:', got, ',', SUB1 == got
    !
    ! Inexact representation of the second smallest subnormal number.
    buff = '9e-324'
    read (buff, *) got
    print *, 'Expected:', SUB2, ', got:', got, ',', SUB2 == got
    !
    ! Exact representation of the number which is exactly halfway
    ! between the smallest and the second smallest subnormal number
    ! 2**(-1074) + 2**(-1075). This number should be rounded to the
    ! second smallest subnormal number according to the default IEEE
    ! 754 rounding rules:
    buff = '7.41098468761869816264853189302332058547589703921&
    &4871466383785237510132609053131277979497545424539&
    &8856969484704316857659638998506553390969459816219&
    &4016172817189451069785467106791768725751773473155&
    &5330779540854980960845750095811137303474765809687&
    &1009590975442271004757307809711118935784838675653&
    &9987835030152280559340465937397917907387238682993&
    &9581848166016912201945649993128979841136206248449&
    &8678713572180352209017023903285791732520220528974&
    &0208029068540216066123755499834026713000358124864&
    &7904138574340187552090159017259254714629617513415&
    &9774938718574737870961645638908718119841271673056&
    &0170454930047052695901657637768849082679869725733&
    &6652176556794107250876433756084600398490497214911&
    &7463085539556354188641513168478436313080237596295&
    &773983001708984375e-324'
    read (buff, *) got
    print *, 'Expected:', SUB2, ', got:', got, ',', SUB2 == got
    !
    end program test

    I tried the program on Windows 7 with gfortran 11.2.0 and on
    Windows 10 with gfortran 12.2.0. Both are from MSYS2/MinGW64
    and the results are identical:

    Expected: 4.9406564584124654E-324 , got: 4.9406564584124654E-324, T
    Expected: 9.8813129168249309E-324 , got: 9.8813129168249309E-324, T
    Expected: 9.8813129168249309E-324 , got: 2.2250738585072014E-308, F

    The third print should give the same result as the second one.
    The result looks like the smallest normal double precision number
    which is not quiet correct.

    On Windows 10 with the Intel ifort 64-Bit compiler version 2021.5.0
    Build 20211109_000000:

    Expected: 4.940656458412465E-324 , got: 4.940656458412465E-324, T
    Expected: 9.881312916824931E-324 , got: 9.881312916824931E-324, T
    Expected: 9.881312916824931E-324 , got: 9.881312916824931E-324, T

    Can someone please test the program on Linux to verify that this
    is not a Windows specific problem. Is this a known issue?

    Regards

    --
    Thomas

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Thomas Schnurrenberger on Thu Oct 13 10:40:28 2022
    On Thursday, October 13, 2022 at 5:42:40 AM UTC-7, Thomas Schnurrenberger wrote:
    The following program gives an unexpected result when compiled and
    executed with gfortran on Windows:

    (snip)

    Expected: 4.9406564584124654E-324 , got: 4.9406564584124654E-324, T
    Expected: 9.8813129168249309E-324 , got: 9.8813129168249309E-324, T
    Expected: 9.8813129168249309E-324 , got: 2.2250738585072014E-308, F

    Can someone please test the program on Linux to verify that this
    is not a Windows specific problem. Is this a known issue?

    Personally, I believe that subnormals were a bad idea.
    They give a slightly greater exponent range, at a complication in hardware. (Or, even worse, in some cases software.)

    IEEE provides some bit representations for floating point values, and also some suggestions on how to use them.

    As well as I know, it is possible to use the IEEE formats without necessarily following all the IEEE rules on using them.

    Conversion between textual decimal representation and internal binary representation is not easy. I would especially be surprised if any conversion could use 722 digits in the conversion process.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter Klausler US@21:1/5 to All on Thu Oct 13 11:02:54 2022
    On Thursday, October 13, 2022 at 10:40:30 AM UTC-7, gah4 wrote:
    Conversion between textual decimal representation and internal binary representation is not easy. I would especially be surprised if any conversion
    could use 722 digits in the conversion process.

    128-bit IEEE is even more fun, but I don't know of a Fortran compiler that has a limit on digits that would preclude exact conversions.

    $ cat t.f90
    print '(E11550.11540E4)', real(z'1', kind=16)
    end
    $ flang t.f90
    $ ./a.out
    0.64751751194380251109244389582276465524995693380346810096898843891970395401241193710176714912766499402558781414768481196765872198863825420466851100719726179830427927107513349344167346256384717402394485265055539903914555562521711480680708220346882569824
    762728287891030283573375613480310623865645926398262269919079078676632620657112115830646571960683083328452344530697605264894476609645793137514034026318043500399488700752556487133680661178794031557667133034674349370624094116852151376073331394228438350516689
    835671671968026429523535040797143471038605377828937002155211686677110429506100218815136279864294617004333392019353974988251843353855148928443399308529678384486821255023041141221530459464654630847641101744787370443353123896614836392105539434114765447862613
    978750641914512267676146258927903699614150696069800070805027886489199759168018782220022523817230472309718765709954288212192815965476330235387831371836463969528315305510686834195967353740867462905258679962169053233653198851726099568276255110363324783532289
    476318800506845591506083189865215401360612737714933904127847565521038975185277641587787593338807148822796333238263973123754069270394465253064478385143715036549878551723063075841554598267070959096177525268004013269908287216337267704409154390926779066467985
    735241991166482642069204511601336350713617738121217165281781482407207832267365496237361352749903091381431832483719598759788050275009286938080733369557527590884428656000751998889983238806435496700555054213624351085727320873229820271877724592312289894723729
    518643210992618787810843302529883339213629989633037224310597419687634524069538350151205337733852899047108436284027002747028704740738252488288899849942846076048472117942212107299131598290142171680044610495326626965429131836281571995616419499239366293689928
    566213830845453276369722655423553417498556630200048873168352161567672230537998110672589138084699942326078588545240644321457759221445357012364689857052129770454794895156900093889236255806857887076058773438576691708946567974233684903294072511603933560488206
    070850890690254135842698167397472112395135504143831175088267631435128620064970580411452960978929179999355770532342526986919337927247536821845376828355628299386300048383843639442431376228649182574742562801272911169650506001781204777207847421842053761959758
    316777217647400445366246457644713815714523818301253987651520832874831102793946978559157139819399706845991995948630072306240767861396175546314507349951900819321876168142346327387782244332564637383464352749057109255811060612738409755929317612667992655877654
    689467643370851923693583162984574500088094285869215047437308738957104746144800037271461623498583332915165521625453703122003908415883094809732746316462735973902494777466571318911964823986701187979100989188996894821969566606382257319606935427639643023089996
    929570910613001836483297851827933014072672000463830430052367599773876014077691103832957299186545209377855863906331570203476328121087286385898132825695295767693671733247640852857053083129549574015582471687399314465694228187234824710973743621052792785585707
    462781683315969037995279590016748561555646198214070447997200206206422332460578482364760475407628497883254356305924201944904435394289908994886558901838867886505185955421802579392005396450418083877602381895624283517746324406226180569131374998200219247331736
    680368064857334435670396138660371761559552538275484733604405170494226960755011832925730632506130211675038585610822383744391934132314726080728887333265128532878067733890732992973727602443973557915020046544581187280375103290341206430301823467160119749967195
    989342776352977629588372473893669097633674936822994303626689961939354052262211802804626913539122824557017598100371164399688836395961089264135288262005025115510716615410712418923190708129942695180863852959923810259571729923993121414142102355477070085555900
    495092940483311782588856452542957378349275903327731058438267977565400398102950216990377882282050721467380943202619808232520968528756705913661945565955494703620903172333491281604756262932465384300392264638772535178550629818900587124158665787276943628778050
    785941159390499226972156891390428844758297982013992218433398431443343297509762650543758986370876194067763578623415995395857721733625699297232173138562186107390799116939283955733541076952079243894430477359860970571171027616473985837467040662221924896284915
    792418615122284579427276776562170680603040634318594449990928730955468080358940711938726769242078935950513340678708669785852410632983994488016649795035762587308531377626567159326745848784087650743487153508082111604880375673700824495969140443786313843515745
    145744072662686015184181211406390177729507554398223521426054656397563309371854348127764374551700527042548736895259894456527815594746442275376849643216259462006473477261004688754457975922911923637246411006025717239601043897275614876162138938801586992615653
    538603942684125194782507558821215023508557775489873549571876113646443477834606239185697903577120787080300717298621472041190620031457830576579643356204906866547777758577724172306540056693801372721886501045028595632825356427345334305672873194983045289158766
    383702966072096547272468101207491470115798460076868768723489787676101970181674441015326565006995864076744043252493801870669562288776212062811301410353399292598950872168099763560393041763246150512238636421329874939892820961320237196286751796597930994411242
    341813545830826363061154303352482566365955427530635779461773992943363184596117548311896570650796799349281291132951894116607493062267470617533167604802907608464213475575536071852544625149916347891632155925545652886250214290645942174440344350946354898012946
    360442171418941286085602008379429011040147137830390465872288338880327095137327001016670028338850101424076202334381068610870620559068748728934911336784842597208208863977244389399443264499425166966286835100304262372577654262695325952481832896116023739523050
    738270294258384810074433614811720336641998936149326235543781013133539256991627675818094441749572935326410341123671639404724964548266454966082684914359753307547920224734132546416353091313653600139149095199632360469528970893470161367389841331337908741011431
    686910221419189677978774764501005850673487661832249908142536107635929747317842638328536750453432465332549661313115314110684787104297867918114046586808055881057685182920981292591641511531266153414983793243539534507238740924011520157876288793906037850575223
    750883227793640070184335825436730909908333522963022903901653366473552423659829036706485637272392835472412020290219019934934532314075439425333743031288555447188546811338187037173096159995636170260693602081563932149243338560377267712598579312984879090067829
    871959268359105372792135829056673849357458714838807249596853772844554513250093893591153563418597475483020757156144398767123041139956792509074548838953023966323816532305320326954817512319400628560244566563812207134134313254444837575342624493396751472142430
    791445986588082025489263121205966978633565547223481141949694091740724553722213548261898820239225248760549359059294542589255053878980395283290766895511089323428562436979996379382280686655953458559782154202745585623685902364677118847705126663283067562865593
    485746362729164143323499922252773790719520952344430418200548549703239314040776103237309889148891883561275339140748561070864798315847397556221068349713689973342464322640127572616289542136261777971272898183575589265919111753761345547373676729412244169665991
    445206880330323884944645974816006842331799696887133771539691070148205865001878900284197599666291258969038597244820185515673684593394372820274731637136305543701465182810680497018495750897434323493088492814561827450270118456536262907807382991813057724820012
    509917610475433447904546259431560850446611035765125233661613510996407511353851483059139878890086980092343709418913460983064379376612271723865069806369037435412852356057801672160089208286108420665220965895004209406064056926641099050632348661170775163086941
    757091232194762832302902074975551594671499793470202096735004966510235544750050539912953744307285247712124351073826643188427031978119010750270367030414193152291562632797088650640044733924017108175330402101527579666914164718363614985462491808660490397382942
    658638649254061357524285371598801320610428280907727331035614370210709388355204849875647849023578266450061853848472997115130425589131165506798429817857377137257900451280944116762648585732015290736780733963875192683737985825482638685921196660973811892552471
    906413521954430814329459819012237167457125437448471465030124600852161483358076196245283960690103708719816427127559329694845011551844874545978463757825988097080968936454398564786345081468590659781793510075807449289741145297882152264846018249741401073527587
    763789938000084794636404597737881060392216475279156196383758972796539468670573663378347212655000810356953729581870773676338484263513459595376441312553938869498280409661127680137456714766222219731722990213227238306843450548181574845017601137342996622982420
    394596944840746718088801262619639993014008335753665872202391804438859486349114326724549095784795869760645981266331778350118248120404400905297369154365643303177843432609414191990079945655563361956549947677683916418431672912425878824000912081243486699963430
    700610267325545874287799764395122591617370363358476823467285395497784933888705281029698229239764540224773220752049054203778238008765407245607822425400433584943057586483900713885561429549914408950260343422977546243874727326974232602110147317291961391725140
    539525914282478873832433447553891044960379753606772247655912119703822122259427975920052726807873862393039466894232937091489659994007959050737566970259675643966610274896063378721528541518875744009791508702959780667730599131031413380942061404461535957846596
    961169994512656270491627452814928318460338657079083049449757325746370901021307528602414961598977205665237114776739104923762572450196572717344514175659320348463410700930182627775077900261223027756801790257236852308834599246314626021755359780018362732357411
    642830346618712385372858319671074551751753535839070739214284733756952051790778559251708819222624804375884738892604238619410922374901606937212732406203867643351949310883489767987593674328357822783151502927183300462531882485372216004105175520380011017474788
    028906062599491204428761237835908855606562524601863579050091407619143991859866774393729755965509497071402000661849634862596730547395123886875782636441382145663125435453597270764337830374274650419536692568366947425227378669092588107437395795053686796107362
    749016500024070423872851964779086582045166346561971622339566877672226418816295873094916146723251141143910465492206472033714246298615982883833464876645673193387374322536302367207068826060198721670883870486731458615363090131349551311164222870171367924075637
    591840675748580255062139022593061492616809927526045793365723366505991850081080076078345252003916680026723603176735311981150759594908474221403177433019529518487314155168026579189575826869625019580587272880939451128445893971171233416351919888199706464118260
    700198467216414695910921640244013953434891479650705838116011056742366554042500373832895491218324603334786154100353121313597345196743578362465084391591890717383427522967952200117414999858207114551391874591355785209598616706102249254557412070590946252434411
    199061493512410984346297239238119679218216929431383849185152962764253480336296906549929910148259535067627152699210596536358136488677162709710373032645406398557604551437160704207508866481964709272392954477248411151647112642751667401332043112824364716305617
    491407448724357546337992985741038864944130182266235351562500000000000E-4965
    $ ./a.out >tmp
    $ cat t2.f90
    real(16) x
    read (*, '(E12000.0)') x
    write (*, '(Z16)') x
    end
    $ flang t2.f90
    $ ./a.out <tmp
    1

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter Klausler US@21:1/5 to All on Thu Oct 13 11:44:00 2022
    On Thursday, October 13, 2022 at 11:26:44 AM UTC-7, gah4 wrote:
    Are there cases where changing the 722nd digit will change the value?

    I think that one could find such cases when it changes rounding, especially when those changed digits are being read back into a more precise kind of real.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Peter Klausler US on Thu Oct 13 11:26:42 2022
    On Thursday, October 13, 2022 at 11:02:57 AM UTC-7, Peter Klausler US wrote:
    On Thursday, October 13, 2022 at 10:40:30 AM UTC-7, gah4 wrote:
    Conversion between textual decimal representation and internal binary representation is not easy. I would especially be surprised if any conversion
    could use 722 digits in the conversion process.

    128-bit IEEE is even more fun, but I don't know of a Fortran compiler that has a limit on digits that would preclude exact conversions.

    I got interested in this in the Fortran 66 days, and had the OS/360
    Fortran library to read, and figure out how they did it. I haven't tried
    to follow actual library routines since then.

    OK, more specifically on what I wrote.

    Are there cases where changing the 722nd digit will change the value?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From jfh@21:1/5 to Thomas Schnurrenberger on Thu Oct 13 13:22:20 2022
    On Friday, October 14, 2022 at 1:42:40 AM UTC+13, Thomas Schnurrenberger wrote:
    The following program gives an unexpected result when compiled and
    executed with gfortran on Windows:

    program test
    !
    use :: iso_fortran_env
    !
    implicit none
    !
    real(real64), parameter :: SUB1 = real(z'1', real64)
    real(real64), parameter :: SUB2 = real(z'2', real64)
    !
    character(len=1000) :: buff
    real(real64) :: got
    !
    ! Inexact representation of the smallest subnormal number:
    buff = '5e-324'
    read (buff, *) got
    print *, 'Expected:', SUB1, ', got:', got, ',', SUB1 == got
    !
    ! Inexact representation of the second smallest subnormal number.
    buff = '9e-324'
    read (buff, *) got
    print *, 'Expected:', SUB2, ', got:', got, ',', SUB2 == got
    !
    ! Exact representation of the number which is exactly halfway
    ! between the smallest and the second smallest subnormal number
    ! 2**(-1074) + 2**(-1075). This number should be rounded to the
    ! second smallest subnormal number according to the default IEEE
    ! 754 rounding rules:
    buff = '7.41098468761869816264853189302332058547589703921& &4871466383785237510132609053131277979497545424539& &8856969484704316857659638998506553390969459816219& &4016172817189451069785467106791768725751773473155& &5330779540854980960845750095811137303474765809687& &1009590975442271004757307809711118935784838675653& &9987835030152280559340465937397917907387238682993& &9581848166016912201945649993128979841136206248449& &8678713572180352209017023903285791732520220528974& &0208029068540216066123755499834026713000358124864& &7904138574340187552090159017259254714629617513415& &9774938718574737870961645638908718119841271673056& &0170454930047052695901657637768849082679869725733& &6652176556794107250876433756084600398490497214911& &7463085539556354188641513168478436313080237596295&
    &773983001708984375e-324'
    read (buff, *) got
    print *, 'Expected:', SUB2, ', got:', got, ',', SUB2 == got
    !
    end program test

    I tried the program on Windows 7 with gfortran 11.2.0 and on
    Windows 10 with gfortran 12.2.0. Both are from MSYS2/MinGW64
    and the results are identical:

    Expected: 4.9406564584124654E-324 , got: 4.9406564584124654E-324, T
    Expected: 9.8813129168249309E-324 , got: 9.8813129168249309E-324, T
    Expected: 9.8813129168249309E-324 , got: 2.2250738585072014E-308, F

    The third print should give the same result as the second one.
    The result looks like the smallest normal double precision number
    which is not quiet correct.

    On Windows 10 with the Intel ifort 64-Bit compiler version 2021.5.0
    Build 20211109_000000:

    Expected: 4.940656458412465E-324 , got: 4.940656458412465E-324, T
    Expected: 9.881312916824931E-324 , got: 9.881312916824931E-324, T
    Expected: 9.881312916824931E-324 , got: 9.881312916824931E-324, T

    Can someone please test the program on Linux to verify that this
    is not a Windows specific problem. Is this a known issue?

    Regards

    --
    Thomas

    On my Linux Ubuntu system, after putting in this line after the declarations:

    print *, 'version = ',compiler_version()

    I got these results with gfortran and ifort.

    version = GCC version 12.1.0
    Expected: 4.9406564584124654E-324 , got: 4.9406564584124654E-324 , T
    Expected: 9.8813129168249309E-324 , got: 9.8813129168249309E-324 , T
    Expected: 9.8813129168249309E-324 , got: 9.8813129168249309E-324 , T

    version =
    Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel
    (R) 64, Version 2021.6.0 Build 20220226_000000
    Expected: 4.940656458412465E-324 , got: 4.940656458412465E-324 , T
    Expected: 9.881312916824931E-324 , got: 9.881312916824931E-324 , T
    Expected: 9.881312916824931E-324 , got: 9.881312916824931E-324 , T

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steven G. Kargl@21:1/5 to Thomas Schnurrenberger on Thu Oct 13 22:43:50 2022
    On Thu, 13 Oct 2022 14:42:37 +0200, Thomas Schnurrenberger wrote:

    The following program gives an unexpected result when compiled and
    executed with gfortran on Windows:

    program test
    !
    use :: iso_fortran_env
    !
    implicit none
    !
    real(real64), parameter :: SUB1 = real(z'1', real64)
    real(real64), parameter :: SUB2 = real(z'2', real64)
    !

    Why do you think that there is a problem? REAL64 from
    ISO_FORTRAN_ENV does not mean IEEE 754 binary64 type.
    It means the type occupies 64 bits. That's it. In fact,
    the type many not support subnormals at all.

    If you want IEEE binary64, then use the IEEE 754 facilities
    available in modern Fortran.

    --
    steve

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter Klausler US@21:1/5 to Thomas Schnurrenberger on Thu Oct 13 16:01:07 2022
    On Thursday, October 13, 2022 at 5:42:40 AM UTC-7, Thomas Schnurrenberger wrote:
    Expected: 4.9406564584124654E-324 , got: 4.9406564584124654E-324, T
    Expected: 9.8813129168249309E-324 , got: 9.8813129168249309E-324, T
    Expected: 9.8813129168249309E-324 , got: 2.2250738585072014E-308, F

    The third print should give the same result as the second one.
    The result looks like the smallest normal double precision number
    which is not quiet correct.

    I checked your decimal numbers, and they are accurate. But the results *are* correct -- when the
    default "round to nearest" mode is in effect, and the exact value is exactly between two representable
    numbers, IEEE-754 rounds to the *even* one -- i.e., the one whose least-significant bit is zero. And
    in this case, that's z'2', not z'1'.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Schnurrenberger@21:1/5 to jfh on Fri Oct 14 07:53:41 2022
    On 13.10.2022 22:22, jfh wrote:
    On Friday, October 14, 2022 at 1:42:40 AM UTC+13, Thomas Schnurrenberger wrote:
    The following program gives an unexpected result when compiled and
    executed with gfortran on Windows:

    program test
    !
    use :: iso_fortran_env
    !
    implicit none
    !
    real(real64), parameter :: SUB1 = real(z'1', real64)
    real(real64), parameter :: SUB2 = real(z'2', real64)
    !
    character(len=1000) :: buff
    real(real64) :: got
    !
    ! Inexact representation of the smallest subnormal number:
    buff = '5e-324'
    read (buff, *) got
    print *, 'Expected:', SUB1, ', got:', got, ',', SUB1 == got
    !
    ! Inexact representation of the second smallest subnormal number.
    buff = '9e-324'
    read (buff, *) got
    print *, 'Expected:', SUB2, ', got:', got, ',', SUB2 == got
    !
    ! Exact representation of the number which is exactly halfway
    ! between the smallest and the second smallest subnormal number
    ! 2**(-1074) + 2**(-1075). This number should be rounded to the
    ! second smallest subnormal number according to the default IEEE
    ! 754 rounding rules:
    buff = '7.41098468761869816264853189302332058547589703921&
    &4871466383785237510132609053131277979497545424539&
    &8856969484704316857659638998506553390969459816219&
    &4016172817189451069785467106791768725751773473155&
    &5330779540854980960845750095811137303474765809687&
    &1009590975442271004757307809711118935784838675653&
    &9987835030152280559340465937397917907387238682993&
    &9581848166016912201945649993128979841136206248449&
    &8678713572180352209017023903285791732520220528974&
    &0208029068540216066123755499834026713000358124864&
    &7904138574340187552090159017259254714629617513415&
    &9774938718574737870961645638908718119841271673056&
    &0170454930047052695901657637768849082679869725733&
    &6652176556794107250876433756084600398490497214911&
    &7463085539556354188641513168478436313080237596295&
    &773983001708984375e-324'
    read (buff, *) got
    print *, 'Expected:', SUB2, ', got:', got, ',', SUB2 == got
    !
    end program test

    I tried the program on Windows 7 with gfortran 11.2.0 and on
    Windows 10 with gfortran 12.2.0. Both are from MSYS2/MinGW64
    and the results are identical:

    Expected: 4.9406564584124654E-324 , got: 4.9406564584124654E-324, T
    Expected: 9.8813129168249309E-324 , got: 9.8813129168249309E-324, T
    Expected: 9.8813129168249309E-324 , got: 2.2250738585072014E-308, F

    The third print should give the same result as the second one.
    The result looks like the smallest normal double precision number
    which is not quiet correct.

    On Windows 10 with the Intel ifort 64-Bit compiler version 2021.5.0
    Build 20211109_000000:

    Expected: 4.940656458412465E-324 , got: 4.940656458412465E-324, T
    Expected: 9.881312916824931E-324 , got: 9.881312916824931E-324, T
    Expected: 9.881312916824931E-324 , got: 9.881312916824931E-324, T

    Can someone please test the program on Linux to verify that this
    is not a Windows specific problem. Is this a known issue?

    Regards

    --
    Thomas

    On my Linux Ubuntu system, after putting in this line after the declarations:

    print *, 'version = ',compiler_version()

    I got these results with gfortran and ifort.

    version = GCC version 12.1.0
    Expected: 4.9406564584124654E-324 , got: 4.9406564584124654E-324 , T
    Expected: 9.8813129168249309E-324 , got: 9.8813129168249309E-324 , T
    Expected: 9.8813129168249309E-324 , got: 9.8813129168249309E-324 , T

    version =
    Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel
    (R) 64, Version 2021.6.0 Build 20220226_000000
    Expected: 4.940656458412465E-324 , got: 4.940656458412465E-324 , T
    Expected: 9.881312916824931E-324 , got: 9.881312916824931E-324 , T
    Expected: 9.881312916824931E-324 , got: 9.881312916824931E-324 , T

    Thanks for checking. It seems, the problem exists only on Windows.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Schnurrenberger@21:1/5 to Peter Klausler US on Fri Oct 14 08:46:26 2022
    On 14.10.2022 01:01, Peter Klausler US wrote:
    On Thursday, October 13, 2022 at 5:42:40 AM UTC-7, Thomas Schnurrenberger wrote:
    Expected: 4.9406564584124654E-324 , got: 4.9406564584124654E-324, T
    Expected: 9.8813129168249309E-324 , got: 9.8813129168249309E-324, T
    Expected: 9.8813129168249309E-324 , got: 2.2250738585072014E-308, F

    The third print should give the same result as the second one.
    The result looks like the smallest normal double precision number
    which is not quiet correct.

    I checked your decimal numbers, and they are accurate. But the results *are* correct -- when the
    default "round to nearest" mode is in effect, and the exact value is exactly between two representable
    numbers, IEEE-754 rounds to the *even* one -- i.e., the one whose least-significant bit is zero. And
    in this case, that's z'2', not z'1'.

    Thanks for verifying my numbers. I agree completely with you, except
    that all the results are correct.

    This is the output of the third print:

    Expected: 9.8813129168249309E-324 , got: 2.2250738585072014E-308, F

    The result is in my opinion not correct, and it is not a "simple"
    rounding error. If you change the last digit of the input number from
    5 to 4, gfortran returns the correct result, which is z'1'. If you
    change the last digit from 5 to 6, gfortran returns also the correct
    result which is z'2'. It is only this exact number which gives a
    incorrect result. What do you expect as result when reading the large
    input number?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter Klausler US@21:1/5 to Thomas Schnurrenberger on Fri Oct 14 10:11:23 2022
    On Thursday, October 13, 2022 at 11:46:29 PM UTC-7, Thomas Schnurrenberger wrote:
    This is the output of the third print:
    Expected: 9.8813129168249309E-324 , got: 2.2250738585072014E-308, F
    The result is in my opinion not correct, and it is not a "simple"
    rounding error. If you change the last digit of the input number from
    5 to 4, gfortran returns the correct result, which is z'1'. If you
    change the last digit from 5 to 6, gfortran returns also the correct
    result which is z'2'. It is only this exact number which gives a
    incorrect result. What do you expect as result when reading the large
    input number?

    4 should round down to z'1', 6 should round up to z'2', and 5 is exactly between them and should round to the even one, which is z'2'.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Schnurrenberger@21:1/5 to Steven G. Kargl on Mon Oct 17 13:04:03 2022
    On 14.10.2022 00:43, Steven G. Kargl wrote:
    On Thu, 13 Oct 2022 14:42:37 +0200, Thomas Schnurrenberger wrote:

    The following program gives an unexpected result when compiled and
    executed with gfortran on Windows:

    program test
    !
    use :: iso_fortran_env
    !
    implicit none
    !
    real(real64), parameter :: SUB1 = real(z'1', real64)
    real(real64), parameter :: SUB2 = real(z'2', real64)
    !

    Why do you think that there is a problem? REAL64 from
    ISO_FORTRAN_ENV does not mean IEEE 754 binary64 type.
    It means the type occupies 64 bits. That's it. In fact,
    the type many not support subnormals at all.

    You are of course right.

    If you want IEEE binary64, then use the IEEE 754 facilities
    available in modern Fortran.

    The following modified program is an attempt to use the IEEE 754
    facilities correctly:

    program test
    !
    use, intrinsic :: ieee_arithmetic
    use, intrinsic :: ieee_features
    use, intrinsic :: iso_fortran_env, only: compiler_version
    !
    implicit none
    !
    ! Select a suitable IEEE real kind.
    integer, parameter :: dp = ieee_selected_real_kind(15)
    !
    character(len=1000) :: buff
    real(dp) :: expected, got
    logical :: features(4)
    !
    print *, 'Compiler version = ', compiler_version()
    print *, '-----'
    if (dp < 0) stop 'No suitable IEEE real kind found.'
    ! Get IEEE features.
    features(1) = ieee_support_subnormal(got)
    features(2) = ieee_support_io(got)
    features(3) = ieee_support_rounding(ieee_nearest, got)
    features(4) = ieee_support_underflow_control(got)
    print *, 'The selected real kind supports the following IEEE features:'
    if (features(1)) print *, 'Subnormal numbers.'
    if (features(2)) print *, 'Formatted input/output.'
    if (features(3)) print *, 'Control of the rounding mode.'
    if (features(4)) print *, 'Control of the underflow mode.'
    if (.not. all(features)) stop &
    'Not all required IEEE features are supported.'
    print *, 'Set rounding mode and underflow control:'
    ! Set rounding mode to nearest.
    call ieee_set_rounding_mode(ieee_nearest)
    print *, 'Rounding mode set to nearest.'
    ! Enable gradual underflow.
    call ieee_set_underflow_mode(.true.)
    print *, 'Gradual underflow is enabled.'
    print *, '-----'
    !
    ! Inexact representation of the smallest subnormal number:
    buff = '5e-324'
    expected = ieee_scalb(1.0_dp, -1074)
    read (buff, *) got
    print *, '1: Expected:', expected, ', got:', got, ',', expected == got
    !
    ! Inexact representation of the second smallest subnormal number.
    buff = '9e-324'
    expected = ieee_scalb(2.0_dp, -1074)
    read (buff, *) got
    print *, '2: Expected:', expected, ', got:', got, ',', expected == got
    !
    ! Exact representation of the number which is exactly halfway
    ! between the smallest and the second smallest subnormal number
    ! 2**(-1074) + 2**(-1075). This number should be rounded to the
    ! second smallest subnormal number according to the default IEEE
    ! 754 rounding rules:
    buff = '7.41098468761869816264853189302332058547589703921&
    &4871466383785237510132609053131277979497545424539&
    &8856969484704316857659638998506553390969459816219&
    &4016172817189451069785467106791768725751773473155&
    &5330779540854980960845750095811137303474765809687&
    &1009590975442271004757307809711118935784838675653&
    &9987835030152280559340465937397917907387238682993&
    &9581848166016912201945649993128979841136206248449&
    &8678713572180352209017023903285791732520220528974&
    &0208029068540216066123755499834026713000358124864&
    &7904138574340187552090159017259254714629617513415&
    &9774938718574737870961645638908718119841271673056&
    &0170454930047052695901657637768849082679869725733&
    &6652176556794107250876433756084600398490497214911&
    &7463085539556354188641513168478436313080237596295&
    &773983001708984375e-324'
    expected = ieee_scalb(3.0_dp, -1075)
    read (buff, *) got
    print *, '3: Expected:', expected, ', got:', got, ',', expected == got
    !
    end program test


    Results from running the program on Windows 10
    (results slightly edited for display purpose):

    Compiler version = GCC version 12.2.0
    -----
    The selected real kind supports the following IEEE features:
    Subnormal numbers.
    Formatted input/output.
    Control of the rounding mode.
    Control of the underflow mode.
    Set rounding mode and underflow control:
    Rounding mode set to nearest.
    Gradual underflow is enabled.
    -----
    1: Expected: 4.9406564584124654E-324, got: 4.9406564584124654E-324, T
    2: Expected: 9.8813129168249309E-324, got: 9.8813129168249309E-324, T
    3: Expected: 9.8813129168249309E-324, got: 2.2250738585072014E-308, F


    Compiler version =
    Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running
    on Intel
    (R) 64, Version 2021.7.0 Build 20220726_000000
    -----
    The selected real kind supports the following IEEE features:
    Subnormal numbers.
    Formatted input/output.
    Control of the rounding mode.
    Control of the underflow mode.
    Set rounding mode and underflow control:
    Rounding mode set to nearest.
    Gradual underflow is enabled.
    -----
    1: Expected: 4.940656458412465E-324, got: 4.940656458412465E-324, T
    2: Expected: 9.881312916824931E-324, got: 9.881312916824931E-324, T
    3: Expected: 9.881312916824931E-324, got: 9.881312916824931E-324, T


    I would expect that the ifort and the gfortran compiler give the same
    results. I'm very grateful for any hint, if I am doing something wrong.

    Regards

    --
    Thomas

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steven G. Kargl@21:1/5 to Thomas Schnurrenberger on Mon Oct 17 17:48:47 2022
    On Mon, 17 Oct 2022 13:04:03 +0200, Thomas Schnurrenberger wrote:

    On 14.10.2022 00:43, Steven G. Kargl wrote:
    On Thu, 13 Oct 2022 14:42:37 +0200, Thomas Schnurrenberger wrote:

    The following program gives an unexpected result when compiled and
    executed with gfortran on Windows:

    program test
    !
    use :: iso_fortran_env
    !
    implicit none
    !
    real(real64), parameter :: SUB1 = real(z'1', real64)
    real(real64), parameter :: SUB2 = real(z'2', real64)
    !

    Why do you think that there is a problem? REAL64 from
    ISO_FORTRAN_ENV does not mean IEEE 754 binary64 type.
    It means the type occupies 64 bits. That's it. In fact,
    the type many not support subnormals at all.

    You are of course right.

    If you want IEEE binary64, then use the IEEE 754 facilities
    available in modern Fortran.

    The following modified program is an attempt to use the IEEE 754
    facilities correctly:


    (program removed to shorten response.



    Results from running the program on Windows 10

    This is your problem.


    Compiler version = GCC version 12.2.0
    ...
    -----
    1: Expected: 4.9406564584124654E-324, got: 4.9406564584124654E-324, T
    2: Expected: 9.8813129168249309E-324, got: 9.8813129168249309E-324, T
    3: Expected: 9.8813129168249309E-324, got: 2.2250738585072014E-308, F

    Compiler version =
    Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running
    on Intel
    (R) 64, Version 2021.7.0 Build 20220726_000000
    ...
    -----
    1: Expected: 4.940656458412465E-324, got: 4.940656458412465E-324, T
    2: Expected: 9.881312916824931E-324, got: 9.881312916824931E-324, T
    3: Expected: 9.881312916824931E-324, got: 9.881312916824931E-324, T


    I would expect that the ifort and the gfortran compiler give the same results. I'm very grateful for any hint, if I am doing something wrong.


    On FreeBSD, you get

    1: Expected: 4.9406564584124654E-324 , got: 4.9406564584124654E-324 , T
    2: Expected: 9.8813129168249309E-324 , got: 9.8813129168249309E-324 , T
    3: Expected: 9.8813129168249309E-324 , got: 9.8813129168249309E-324 , T

    Windows 10 is simply broken for your "BUF = 7.4..."; READ(BUF,*)".

    This eventually gets reduced to a library function from the OS. If you
    look into gcc/libgfortran/libgfortran.h, you find

    #ifdef __MINGW32__
    extern float __strtof (const char *, char **);
    #define gfc_strtof __strtof
    extern double __strtod (const char *, char **);
    #define gfc_strtod __strtod
    extern long double __strtold (const char *, char **);
    #define gfc_strtold __strtold
    #else
    #define gfc_strtof strtof
    #define gfc_strtod strtod
    #define gfc_strtold strtold
    #endif

    On FreeBSD, I have
    nm /usr/local/lib/gcc11/libgfortran.a | grep strtof
    U strtof
    w strtoflt128
    U strtoflt128

    So either __strtof or strtof on Windows 10 appears to be broken.

    --
    steve

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Thomas Schnurrenberger on Mon Oct 17 19:20:21 2022
    On Thursday, October 13, 2022 at 5:42:40 AM UTC-7, Thomas Schnurrenberger wrote:
    The following program gives an unexpected result when compiled and
    executed with gfortran on Windows:

    Reading the Wikipedia article:

    https://en.wikipedia.org/wiki/IEEE_754#Character_representation

    suggests that the standard requires one be able to take an internal binary value,
    convert it to printable decimal with sufficient digits, and convert back with proper
    rounding to the original binary value.

    It does not seem to require 722 digit values to convert exactly.

    But maybe that page doesn't have everything.

    Is there a place where it says that 722 digits are required?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to All on Wed Oct 19 01:54:10 2022
    On Monday, October 17, 2022 at 7:20:23 PM UTC-7, gah4 wrote:
    On Thursday, October 13, 2022 at 5:42:40 AM UTC-7, Thomas Schnurrenberger wrote:
    The following program gives an unexpected result when compiled and
    executed with gfortran on Windows:
    Reading the Wikipedia article:

    https://en.wikipedia.org/wiki/IEEE_754#Character_representation

    suggests that the standard requires one be able to take an internal binary value,
    convert it to printable decimal with sufficient digits, and convert back with proper
    rounding to the original binary value.

    Discussion on the above page gives the M+3 rule, which as well as I know it,
    is you figure out how many decimal digits are needed to represent the
    precision of the binary value, round up to the nearest integer, and add 3.

    That is said to be what is needed such that the result, converted back to binary, rounds to the original value.

    I believe this is what Java uses for output conversion, whether you want
    it or not.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Schnurrenberger@21:1/5 to All on Wed Oct 19 11:53:39 2022
    On 18.10.2022 04:20, gah4 wrote:
    On Thursday, October 13, 2022 at 5:42:40 AM UTC-7, Thomas Schnurrenberger wrote:
    The following program gives an unexpected result when compiled and
    executed with gfortran on Windows:

    Reading the Wikipedia article:

    https://en.wikipedia.org/wiki/IEEE_754#Character_representation

    suggests that the standard requires one be able to take an internal binary value,
    convert it to printable decimal with sufficient digits, and convert back with proper
    rounding to the original binary value.

    It does not seem to require 722 digit values to convert exactly.

    But maybe that page doesn't have everything.

    Is there a place where it says that 722 digits are required?

    The blog of Rick Regan has a lot of interesting posts about floating
    point numbers: https://www.exploringbinary.com/tag/floating-point/

    Another interesting blog with articles about floating point numbers
    is the blog from Bruce Dawson: https://randomascii.wordpress.com/category/floating-point/

    Regards

    --
    Thomas

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Schnurrenberger@21:1/5 to Steven G. Kargl on Wed Oct 19 16:22:26 2022
    On 17.10.2022 19:48, Steven G. Kargl wrote:
    ...

    This eventually gets reduced to a library function from the OS. If you
    look into gcc/libgfortran/libgfortran.h, you find

    #ifdef __MINGW32__
    extern float __strtof (const char *, char **);
    #define gfc_strtof __strtof
    extern double __strtod (const char *, char **);
    #define gfc_strtod __strtod
    extern long double __strtold (const char *, char **);
    #define gfc_strtold __strtold
    #else
    #define gfc_strtof strtof
    #define gfc_strtod strtod
    #define gfc_strtold strtold
    #endif

    That was the crucial hint, thank you very much. A short test with a
    C program showed indeed that the __strtod() function is responsible for
    the faulty result. After some investigation on the internet, I'm coming
    to the following conclusion:

    The __strto(x) functions are used by the MinGW/MinGW64 projects as
    replacements for faulty implementations in the older Microsoft C
    runtime libraries. Newer Microsoft C runtime libraries, such as the
    "Universal CRT", have correctly working implementations of these
    functions and need no replacements. It shouldn't be necessary to link
    directly to the replacement functions, because the CRT's from
    MinGW/MinGW64 decide themself if this is necessary.

    I would suggest that the gfortran runtime library does not link to the replacement functions. That means, the post-processor definitions for __MINGW32__ can/should be removed.

    I am not an expert in this area, so I would be very grateful if my
    conclusions can be verified by a more involved person. Thanks again
    for your help.

    Regards

    --
    Thomas

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steven G. Kargl@21:1/5 to Thomas Schnurrenberger on Thu Oct 20 17:40:46 2022
    On Wed, 19 Oct 2022 16:22:26 +0200, Thomas Schnurrenberger wrote:

    On 17.10.2022 19:48, Steven G. Kargl wrote:
    ...

    This eventually gets reduced to a library function from the OS. If you
    look into gcc/libgfortran/libgfortran.h, you find

    #ifdef __MINGW32__
    extern float __strtof (const char *, char **);
    #define gfc_strtof __strtof
    extern double __strtod (const char *, char **);
    #define gfc_strtod __strtod
    extern long double __strtold (const char *, char **);
    #define gfc_strtold __strtold
    #else
    #define gfc_strtof strtof
    #define gfc_strtod strtod
    #define gfc_strtold strtold
    #endif

    That was the crucial hint, thank you very much. A short test with a
    C program showed indeed that the __strtod() function is responsible for
    the faulty result. After some investigation on the internet, I'm coming
    to the following conclusion:

    The __strto(x) functions are used by the MinGW/MinGW64 projects as replacements for faulty implementations in the older Microsoft C
    runtime libraries. Newer Microsoft C runtime libraries, such as the "Universal CRT", have correctly working implementations of these
    functions and need no replacements. It shouldn't be necessary to link directly to the replacement functions, because the CRT's from
    MinGW/MinGW64 decide themself if this is necessary.

    I would suggest that the gfortran runtime library does not link to the replacement functions. That means, the post-processor definitions for __MINGW32__ can/should be removed.

    I am not an expert in this area, so I would be very grateful if my conclusions can be verified by a more involved person. Thanks again
    for your help.

    Unfortunately, there has never been a gfortran contributor whose
    primary platform was MS Windows. The one time I interacted with
    a MinGW developer, I was less than thrilled. MingW shadows some
    POSIX function (don't remember, might fstat() or fread()), and I
    asked if they could fix MingW to follow POSIX. The exchange left
    me with little incentive to work on MS Window related gfortran
    bugs.

    You might considering raising a bug report in GCC's bugzilla, but
    it may take awhile to get anyone to fix it.

    --
    steve
    thought I suggested

    Regards

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)