Плавали, знаем. В массив поступает как раз то, что нужно. Причина в алгоритмах конвертации число→строка, и надо добавить такую штуку:
«Если число — по типу Double, по факту точное целое и находится в определённых пределах, преобразовать его в Int64, а затем Int64 в строку».
Сама проверка, является ли double точным целым, довольно сложна. У меня есть код для этого на Си++ (который, в свою очередь, является портом кода из Java). Портанёте на Delphi сами?
enum {
DOUBLE_MANTISSA_BITS = 52,
DOUBLE_MIN_EXPONENT = -1022,
DOUBLE_EXPONENT_BIAS = 1023,
};
#define UC8x(X,Y,Z,T) (static_cast<uint64_t>(0x##X##Y##Z##T##ULL))
#define DOUBLE_MANTISSA_MASK UC8x(000f, ffff, ffff, ffff)
#define DOUBLE_EXPONENT_MASK UC8x(7ff0, 0000, 0000, 0000)
#define DOUBLE_EXPONENT_MASK_HI UC4x(7ff0, 0000)
#define DOUBLE_IMPLICIT_BIT (DOUBLE_MANTISSA_MASK + 1)
union DoubleInt {
double asDouble;
uint64_t asInt;
struct {
uint32_t lo, hi;
} asIntel;
....
}
int DoubleInt::exponent() const
{
return static_cast<int>((
static_cast<int64_t>(asInt & DOUBLE_EXPONENT_MASK) >>
(DOUBLE_MANTISSA_BITS)) - DOUBLE_EXPONENT_BIAS);
}
uint64_t DoubleInt::unsafeMantissa() const
{
int ex = exponent();
uint64_t bits = asInt & DOUBLE_MANTISSA_MASK;
return (ex == DOUBLE_MIN_EXPONENT - 1)
? bits << 1
: bits | DOUBLE_IMPLICIT_BIT;
}
bool DoubleInt::isPreciseInteger() const
{
// функцию isFinite() намеренно упустил, ибо она есть «в коробке» Delphi.
// А вот в Си++ есть не во всех реализациях…
return isFinite()
&& (asDouble == 0.0 ||
DOUBLE_MANTISSA_BITS - numberOfTrailingZeros(unsafeMantissa()) <= exponent());
}
int math::numberOfTrailingZeros(uint64_t i)
{
uint32_t x, y;
if (i == 0u) return 64;
int n = 63;
y = static_cast<uint32_t>(i);
if (y != 0) { n = n -32; x = y; } else x = (int)(i >> 32);
y = x << 16; if (y != 0) { n = n -16; x = y; }
y = x << 8; if (y != 0) { n = n - 8; x = y; }
y = x << 4; if (y != 0) { n = n - 4; x = y; }
y = x << 2; if (y != 0) { n = n - 2; x = y; }
return n - ((x << 1) >> 31);
}
bool math::isPreciseInteger(double x)
{
DoubleInt di;
di.asDouble = x;
return di.isPreciseInteger();
}
Может быть, вам сработают и упрощённые варианты вроде «столбец X — преобразовать в Int64, затем в целое». В промышленной программе этого не хватало.