From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on sa.local.altlinux.org X-Spam-Level: X-Spam-Status: No, score=-4.3 required=5.0 tests=ALL_TRUSTED,BAYES_00, RP_MATCHES_RCVD autolearn=ham autolearn_force=no version=3.4.1 Date: Wed, 29 Apr 2020 16:56:16 +0400 From: Alexey Sheplyakov To: ALT Linux Team development discussions Message-ID: <20200429125616.GA5087@alexnuc> References: <20200425214614.GA7859@gyle.altlinux.org> <20200426142052.GA14178@altlinux.org> <20200427120056.GB28775@altlinux.org> <20200427184056.GA32583@altlinux.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.9.4 (2018-02-28) Subject: [devel] =?utf-8?b?0JzQuNC90YPRgtC60LAg0LzQsNGC0LXQvNCw0YLQuNC6?= =?utf-8?b?0LggKFdhczogUmU6ICBbIzIzODg1NV0gW3Rlc3Qtb25seV0gRkFJTEVEICh0?= =?utf-8?b?cnkgNCkgb3BlbmJsYXMuZ2l0PTAuMy45LWFsdDEgUi1iYXNlLmdpdD00LjAu?= =?utf-8?q?0-alt1=29?= X-BeenThere: devel@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: ALT Linux Team development discussions List-Id: ALT Linux Team development discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Apr 2020 12:57:04 -0000 Archived-At: List-Archive: List-Post: Здравствуйте! On Tue, Apr 28, 2020 at 10:53:03PM +0300, Kirill Maslinsky wrote: > $(R_EXE) на ppc64le зависает не в специфическом месте при сборке, а > вообще всегда при запуске. Похоже, это происходит вот в этом цикле: > > http://git.altlinux.org/people/kirill/packages/R-base.git?p=R-base.git;a=blob;f=src/main/machar.c;h=8db54f1350fe85b0204c7affb4ef79180fc3e5ad;hb=edfd434c0f879f16a9a8f124648df4b4eb23a7e3#l156 > > src/main/machar.c > > 155 for(;;) { > 156 temp = one - a; > 157 if (temp - one != zero) > 158 break; > 159 a = a * beta; > 160 *negep = *negep - 1; > 161 } > > Что бы это могло быть? Исходя из базы (beta) и длины мантиссы (it) пытаются вычислить минимальное число eps, такое, что 1.0 - eps != 1.0 (точнее, его логарифм по основанию beta). Когда этот код писали, еще не было стандарта IEEE 754, , макросов {FLT,DBL,LDBL}_EPS. Приходилось вот так изворачиваться. Но на ppc64 (и некоторых SPARCv9) вместо нормального (IEEE 754) long doulbe почему-то используется double double, т.е. представление числа в виде пары (суммы) двух double. При таком способе большИе числа можно представить точнее, чем double. Например, число 2^53 1/2 можно точно (без округления) представить в виде cуммы "большого" числа 2^53 и "маленького" 1/2. А в double такое число не влезет, 53 бит не хватит, придется округлять. Причем диапазон "маленького" числа гораздо шире, чем у целого той же разрядности (53 бита), ведь есть 11-битный показатель, и им можно масштабировать! Но не выйдет представить с большей (чем double) точностью положительное число, меньшее 2^{-1021}, по той же причине -- показатель все равно 11 бит. Таким образом, у double double длина мантиссы не постоянна и зависит от показателя. А функция MACH_NAME исходит из обратного, т.е. из (в общем-то разумного) предположения, что длина мантисы фиксирована. А теперь вернемся к 1 + eps != 1.0. С помощью "честного" числа с плавающей точкой с длиной мантисы 106 бит (что соответствует паре double) можно представить b1.0000{100 нулей}1, или 1 + 1/2^105. А с помощью double double можно представить даже b1.0{1019 нулей}1 в виде пары (1, 1/2^(-1021)). Потому попытка искать с 149 *negep = *it + 3; или -109, и в дальнейшем *увеличивать* показатель 155 for(;;) { 156 temp = one - a; 157 if (temp - one != zero) 158 break; 159 a = a * beta; 160 *negep = *negep - 1; 161 } заведомо обречена. Поэтому этот цикл никогда не закончится (ну, может когда int со знаком переполнится). К счастью, "подарок" от IBM (double double) легко отключть с помощью флагов компиляции -mabi=ieeelongdouble -mlong-double-128 Такие дела. Простите за много букв. Всего доброго, Алексей