При переносе приложения из Linux x86 в iOS ARM (iPhone 4) я обнаружил разница в поведении по арифметике с плавающей запятой и небольшим значениям.
64-битные числа с плавающей запятой (double) меньше [+/-] 2.2250738585072014E-308 называются denormal/denormalized/subnormal числа в IEEE 754-1985/стандарты IEEE 754-2008.
На iPhone 4 такие маленькие числа обрабатываются как ноль (0), а на x86 для вычисления могут использоваться субнормальные числа.
Я не смог найти никаких объяснений относительно соответствия стандартам IEEE-754 для документации Apple Справочная страница Mac OS X для float (3).
Но благодаря некоторым ответам на Qaru (поведение flush-to-zero в арифметике с плавающей запятой Double vs float на iPhone), я нашел несколько подсказок.
По некоторым данным, кажется, что VFP (или NEON). Математический сопроцессор, используемый по ядру ARM, использует режим Flush-To-Zero (FTZ) (например, субнормальные значения преобразуются в 0 на выходе) и режим Denormals-Are-Zero (DAZ) (например, субнормальные значения преобразуются в 0 при использовании в качестве входных параметров), чтобы обеспечить быстрое аппаратное вычисление IEEE 754.
- Полное соответствие IEEE754 стандарту поддержки ARM
- Режим Run-Fast для близкого соответствия IEEE754 (только для оборудования)
Хорошее объяснение по FTZ и DAZ можно найти в x87 и SSE Плавающая точка помогает в IA-32: Flush-to-Zero (FTZ) и Denormals-Are-Zero (DAZ):
Режимы FTZ и DAZ обрабатывают случаи, когда происходят неверные данные с плавающей запятой или обрабатываются с недостаточным или денормальным условием. [...]. Разница между числом который обрабатывается FTZ и DAZ, очень тонкий. FTZ обрабатывает условия ДАЗ обрабатывает денормалы. Условие underflow возникает, когда вычисление приводит к denormal. В этом случае режим FTZ устанавливает выходной сигнал на ноль. DAZ фиксирует случаи, когда денормалы используются как входные данные, либо как константы, либо путем чтения недопустимой памяти в регистры. Режим DAZ устанавливает входы вычисления до нуля перед вычислением. ЗСТ можно сказать, что он обрабатывает [выход], а DAZ обрабатывает [вход].
Единственное, что касается FTZ на веб-сайте Apple, похоже, находится в iOS ABI Function Call Guide:
Регистр статуса VFP | FPSCR | Специальные | Биты кода состояния (28-31) и биты насыщения (0-4) не сохраняются при вызове функций. Контроль исключений (8-12), режим округления (22-23) и бит с нуля (24) должны быть изменены только конкретными подпрограммами, которые влияют на состояние приложения (включая функции фреймворка API). Короткие длины вектора (16-18) и шага (20-21) должны быть равны нулю при входе и выходе функции. Все остальные биты не должны быть изменены.
Согласно Техническое справочное руководство по ARM1176JZF-S, 18.5 Режимы работы (первый процессор iPhone), VFP может быть настроен на полную поддержку IEEE 754 (sub normal aithmetic), но в этом случае потребуется некоторая поддержка программного обеспечения (захват ядра для вычисления в программном обеспечении).
Примечание. Я также прочитал Debian ARM Hard Float Port и Сравнение VFP.
Мои вопросы:
-
Где можно найти окончательные ответы на вопросы относительно обработки ненормальных чисел на устройствах iOS?
-
Можно ли установить систему iOS для поддержки субормального числа без запроса компилятора произвести только полный программный код с плавающей запятой?
Спасибо.