Если вы хотите вычесть количество дней и отформатировать дату в удобочитаемом формате, вам следует рассмотреть возможность создания пользовательского объекта DateHelper
, который выглядит примерно так:
var DateHelper = {
addDays : function(aDate, numberOfDays) {
aDate.setDate(aDate.getDate() + numberOfDays); // Add numberOfDays
return aDate; // Return the date
},
format : function format(date) {
return [
("0" + date.getDate()).slice(-2), // Get day and pad it with zeroes
("0" + (date.getMonth()+1)).slice(-2), // Get month and pad it with zeroes
date.getFullYear() // Get full year
].join('/'); // Glue the pieces together
}
}
// With this helper, you can now just use one line of readable code to :
// ---------------------------------------------------------------------
// 1. Get the current date
// 2. Subtract 5 days
// 3. Format it
// 4. Output it
// ---------------------------------------------------------------------
document.body.innerHTML = DateHelper.format(DateHelper.addDays(new Date(), -5));
(см. Также эту скрипку )
Нет необходимости, чтобы числа с плавающей запятой и удвоения вели себя по-разному в 32-битном и 64-битном коде, но часто это так. Ответ на ваш вопрос будет зависеть от платформы и компилятора, поэтому вам нужно указать, с какой платформы вы переносите и на какую платформу вы переноситесь.
На платформах Intel x86 32-битный код часто использует сопроцессор x87 набор команд и стек регистров с плавающей запятой для максимальной совместимости, тогда как на платформах amb64 / x86_64 вместо них часто используются инструкции SSE * и регистры xmm *. У них разные характеристики точности.
Редактирование сообщения:
Учитывая вашу платформу, вы можете попробовать использовать -mfpmath = 387 (значение по умолчанию для i386 gcc) в вашей сборке x86_64, чтобы увидеть, объясняет ли это разные результаты.
Ваш компилятор, вероятно, использует коды операций SSE для выполнения большей части своей арифметики с плавающей запятой на 64-битной платформе, предполагающей x86-64, тогда как по соображениям совместимости он, вероятно, раньше использовал FPU для большей части своих операции.
Коды операций SSE предлагают намного больше регистров и единообразия (значения всегда остаются 32-битными или 64-битными), тогда как FPU по возможности использует 80-битные промежуточные значения. Таким образом, вы, скорее всего, раньше извлекали выгоду из этой улучшенной промежуточной точности. (Обратите внимание, что дополнительная точность может привести к непоследовательным результатам, например x == y, но cos (x)! = Cos (y), в зависимости от того, насколько далеко друг от друга происходят вычисления!)
Вы можете попробовать использовать -mfpmath = 387 для ваших 64 битовая версия, поскольку вы компилируете с помощью gcc, и посмотрите, совпадают ли ваши результаты с 32-битными результатами, чтобы сузить круг вопросов.
Как уже говорили другие, вы не предоставили достаточно информации, чтобы точно сказать, что происходит. Но в общем смысле кажется, что вы рассчитывали на какое-то поведение с плавающей запятой, на которое не следует рассчитывать.
В 99 случаях из 100 проблема в том, что вы где-то сравниваете два числа с плавающей запятой. .
Если проблема заключается просто в том, что вы получаете несколько разные ответы, вы должны понимать, что ни один ни один из них не является «правильным» - какое-то округление будет иметь место, несмотря ни на что. архитектура, на которой вы находитесь. Это вопрос понимания значащих цифр в ваших расчетах и осознания того, что любые значения, которые вы придумываете, в определенной степени являются приблизительными.
80-битные внутренние регистры FPU x87 приводят к тому, что его результаты с плавающей запятой немного отличаются от других FPU, которые используют 64-битные внутренние регистры (как на x86_64). Вы получите разные результаты между этими процессорами, если только вы не будете возражать против значительного снижения производительности, сбрасывая данные в память или выполняя другие уловки "strictfp".
См. Также: Округление с плавающей запятой при усечении
В x64 используется набор инструкций SSE2, а в 32-разрядных приложениях по умолчанию часто используется FPU x87.
Последний внутренне сохраняет все значения с плавающей запятой в 80-битном формате. Последний использует простые 32-битные числа с плавающей запятой IEEE.
Кроме того, важно отметить, что вы не должны полагаться на то, что ваши вычисления с плавающей запятой идентичны для разных архитектур .
Даже если вы используете 32-битные сборки на обеих машинах , все еще нет гарантии, что Intel и AMD дадут одинаковые результаты. Конечно, когда один из них запускает 64-битную сборку, вы только добавляете больше неопределенности.
Полагаться на точные результаты операций с плавающей запятой почти всегда было бы ошибкой.
Включение SSE2 в 32-битной версии также было бы хорошим началом, но опять же, не делайте предположений относительно кода с плавающей запятой.
Компилятор GNU имеет множество опций компилятора, связанных с числами с плавающей запятой, которые при некоторых обстоятельствах могут привести к прерыванию вычислений. Просто поищите на этой странице по запросу "float", и вы найдете их.
Очень сложно контролировать многие из этих вещей.
Для начала, стандарт C часто требует, чтобы операции с числами с плавающей запятой выполнялись в "двойном пространстве" и преобразовывались обратно в с плавающей запятой.
У процессоров Intel точность регистров составляет 80 бит, которые они используют для многих из этих операций, а затем они понижают ее до 64 бит при сохранении в основной памяти. Это означает, что значение переменной может измениться без видимой причины.
Вы можете использовать такие вещи, как GnuMP, если вам действительно интересно, и я уверен, что есть и другие библиотеки, которые гарантируют согласованные результаты. В большинстве случаев количество генерируемых ошибок / джиттера ниже реального разрешения, которое вам нужно.
На самом деле сложно получить то, что оба набора результатов верны. Было бы несправедливо характеризовать изменения как что-либо, кроме «других». Возможно, есть повышенная эмоциональная привязанность к более старым результатам ... но нет математической причины предпочитать 32-битные результаты 64-битным результатам.
Рассматривали ли вы возможность использования математики с фиксированной запятой в этом приложении? Математика с фиксированной запятой не только стабильна при изменении микросхемы, компилятора и библиотек, но и во многих случаях быстрее, чем математика с плавающей запятой.
В качестве быстрой проверки переместите двоичный файл из 32-битной системы в 64-битную систему и запустите его. Затем перестройте приложение в 64-битной системе как 32-битный двоичный файл и запустите его. Это может помочь определить, какие изменения на самом деле вызывают расхождение в поведении.
Как уже упоминалось, отличия не должны быть проблемой, если они оба верны. В идеале у вас должны быть модульные тесты для такого рода вещей (чистые вычисления обычно относятся к относительно легкому для тестирования лагерю).
По сути невозможно гарантировать одинаковые результаты для ЦП и инструментальных цепочек (один флаг компилятора может сильно изменить уже), и уже очень трудно быть последовательным. Разработка надежного кода с плавающей запятой - сложная задача, но, к счастью, во многих случаях точность не является проблемой.