From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.oetec.com (mail.oetec.com [108.160.241.186]) by sourceware.org (Postfix) with ESMTPS id D29DF3858D33 for ; Wed, 15 Feb 2023 12:50:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D29DF3858D33 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=blastwave.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=blastwave.org X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,BODY_8BITS,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,KAM_LOTSOFHASH,KAM_SHORT,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-oetec-MailScanner-From: dclarke@blastwave.org X-oetec-MailScanner-SpamCheck: not spam, SpamAssassin (not cached, score=-3.356, required 6, autolearn=not spam, ALL_TRUSTED -1.00, BAYES_00 -1.90, DKIM_SIGNED 0.10, DKIM_VALID -0.10, DKIM_VALID_AU -0.10, DKIM_VALID_EF -0.10, NICE_REPLY_A -0.26, URIBL_BLOCKED 0.00) X-oetec-MailScanner: Found to be clean X-oetec-MailScanner-ID: 31FCodN7497778 X-oetec-MailScanner-Information: Please contact oetec for more information Received: from [172.16.35.9] (cpeac202e7325b3-cmac202e7325b0.cpe.net.cable.rogers.com [99.253.170.241]) (authenticated bits=0) by mail.oetec.com (8.15.2/8.15.2/Debian-22) with ESMTPSA id 31FCodN7497778 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 15 Feb 2023 07:50:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=blastwave.org; s=default; t=1676465440; bh=Qh2mEpB9fn0lvyQ3LX1ckXW5EZE3/5jg4rXb8HtgoII=; h=Date:Subject:To:References:From:In-Reply-To:From; b=cK3nTcLt0a+lf7qwsl3b8g51Z5jDWvfFQQgXyR1GOK0RXPb6TUIixjLikkHY5PObe BhpmsMxgPTRhY/uuO8jaUuGdTvfTDkB2aTn5aobjfQ5ITXTHbMYaX2d5orGs3nUGju mh04reGWPP7fTp1hpEh5ut+J+OIFrWibxCnltnPS5rGEgtv9HeD/YkK/tnjJBHGQ6L uLx8N/uisMgiibPShXN2VHSj6sFQ5vrSWoDAIV/mywMnoUISzQhc2XSZat2nLl8pvo nyhQe2JiIfpLex4ha9tGTgOSodAhy2yEydspaDAsiCJA2z51a+TYJgNc7wjNUuUBEz TG/2st2tKRQkQ== Message-ID: <497b02fa-867e-14cd-6a8b-9d61042a4ad7@blastwave.org> Date: Wed, 15 Feb 2023 07:50:38 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.7.2 Subject: Re: Bytes of long double - trouble . . . To: gcc-help@gcc.gnu.org References: <1675846132.6232748@f313.i.mail.ru> From: Dennis Clarke In-Reply-To: <1675846132.6232748@f313.i.mail.ru> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 2/8/23 03:48, Sergey Smith wrote: > > To:    gcc-help@gcc.gnu.org > Dear GCC,  [ 8:2:23  ] >                   Like Woooew ! What is THIS!?  I installed Visual Studio Code, & your 32 bit C, Version 9.2.0. I ran : >    printf("\nOn THIS particular computer, long double is given %d bytes\n", sizeof(long double)); /* The Answer was: 12 bytes. >    THEN, I updated to C Version 12.2.0 and ran the same code, - ON THE SAME COMPUTER, - but NOW the answer is:  16 bytes ! > >     HOW can this happen if, as I understand it, - this function is supposed to assess a computer’s  *hardware* ?  I am on Windows 10 btw. >                                                                                        — Sergey. > There is no x86 hardware ever that can do true 128-bit long double floating point. The best you can hope for is the strange 10-byte format that Intel made up as a way to extend precision a little bit. Works pretty well for things like fused multiply add and such. However there are various ways you can emulate the IEEE-754 floating point stuff on x86 hardware and perhaps you really want the libquadmath here. Regardless you *may* see the data type take a full 16 bytes and yes that means six bytes are trash. They mean nothing. Unless you do the software emulation goodness. Try : /* * fp128_q.c mess around with the libquadmath to see IEEE-754 2008 * floating point stuff sort of work in an emulated way * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * https://www.gnu.org/licenses/gpl-3.0.txt */ #include #include #include #include #include #include #define BUFFERSIZE 128 int main(int argc, char *argv[]){ __float128 fp0, fp1, fp2, pi; const size_t buffer_size = BUFFERSIZE; char *buffer = calloc(buffer_size,sizeof(unsigned char)); int num_chars; #ifdef FLT_EVAL_METHOD printf ( "INFO : FLT_EVAL_METHOD == %d\n", FLT_EVAL_METHOD); #endif #ifdef DECIMAL_DIG printf ( "INFO : DECIMAL_DIG == %d\n", DECIMAL_DIG); #endif /* LDBL_DIG, FLT_DECIMAL_DIG, DBL_DECIMAL_DIG, LDBL_DECIMAL_DIG */ #ifdef FLT_DECIMAL_DIG printf ( "INFO : FLT_DECIMAL_DIG == %d\n", FLT_DECIMAL_DIG); #endif #ifdef DBL_DECIMAL_DIG printf ( "INFO : DBL_DECIMAL_DIG == %d\n", DBL_DECIMAL_DIG); #endif #ifdef LDBL_DECIMAL_DIG printf ( "INFO : LDBL_DECIMAL_DIG == %d\n", LDBL_DECIMAL_DIG); #endif #ifdef LDBL_DIG printf ( "INFO : LDBL_DIG == %d\n", LDBL_DIG); #endif /* NOTE : floating point can NOT precisely represent the * test values being used here. Such is life in * the real world of floating point. Good luck. */ fp0 = 36.584Q; printf ( "the sizeof(fp0) is %i\n", sizeof(fp0) ); num_chars = quadmath_snprintf(buffer, buffer_size, "%40.36Qg", fp0); if ( num_chars > 0 ) { printf ("INFO : quadmath_snprintf formatted %i chars.\n", num_chars); } else { fprintf(stderr,"FAIL : quadmath_snprintf failed.\n"); return EXIT_FAILURE; } printf ("the value of fp0 is %s\n", buffer); fp1 = 7.812; num_chars = quadmath_snprintf(buffer, buffer_size, "%40.36Qg", fp1); if ( num_chars > 0 ) { printf ("INFO : quadmath_snprintf formatted %i chars.\n", num_chars); } else { fprintf(stderr,"FAIL : wtf quadmath_snprintf failed.\n"); return EXIT_FAILURE; } printf ("the value of fp1 is %s\n", buffer); fp2 = fp0 + fp1; num_chars = quadmath_snprintf(buffer, buffer_size, "%40.36Qg", fp2); if ( num_chars > 0 ) { printf("INFO : quadmath_snprintf formatted %i chars.\n", num_chars); } else { fprintf(stderr,"FAIL : wat? quadmath_snprintf failed.\n"); return EXIT_FAILURE; } printf("fp2 = fp0 + fp1 = %s\n", buffer); /* more than reasonable value for pi which is a few more * decimal digits past the stuff in math.h */ pi = 3.1415926535897932384626433832795028841971693993751Q; num_chars = quadmath_snprintf(buffer, buffer_size, "%46.40Qe", pi ); if ( num_chars > 0 ) { printf ("INFO : quadmath_snprintf formatted %i chars.\n", num_chars); } else { fprintf(stderr,"FAIL : wat? quadmath_snprintf failed.\n"); return EXIT_FAILURE; } printf("libquadmath says pi = %s\n", buffer); printf("the real thing is ~= "); printf("3.1415926535897932384626433832795028841971693993...\n"); free(buffer); return EXIT_SUCCESS; /* or 42 if you prefer */ } Be sure to link with -lquadmath and you should see : $ gcc12 -g -O0 -Wl,-rpath=/usr/local/lib/gcc12,-enable-new-dtags -o fp128_q fp128_q.c -lquadmath $ ./fp128_q INFO : FLT_EVAL_METHOD == 0 INFO : DECIMAL_DIG == 21 INFO : FLT_DECIMAL_DIG == 9 INFO : DBL_DECIMAL_DIG == 17 INFO : LDBL_DECIMAL_DIG == 21 INFO : LDBL_DIG == 18 the sizeof(fp0) is 16 INFO : quadmath_snprintf formatted 40 chars. the value of fp0 is 36.5840000000000000000000000000000015 INFO : quadmath_snprintf formatted 40 chars. the value of fp1 is 7.81200000000000027711166694643907249 INFO : quadmath_snprintf formatted 40 chars. fp2 = fp0 + fp1 = 44.396000000000000277111666946439074 INFO : quadmath_snprintf formatted 46 chars. libquadmath says pi = 3.1415926535897932384626433832795027974791e+00 the real thing is ~= 3.1415926535897932384626433832795028841971693993... Works pretty well. The only other option is to get an IBM POWER9 server which has real 128-bit goodness in hardware. Also an IBM System Z type mainframe can do all that also. The RISC-V processor specification also has the Q-extension for true 128bit floating point but no one seems to have fabricated that. Yet. :) -- Dennis Clarke RISC-V/SPARC/PPC/ARM/CISC UNIX and Linux spoken GreyBeard and suspenders optional