Доступ к паре .first
фактически дает вам ссылку на соответствующую запись, так что rezVector[0].first
будет иметь тип char*&
. Это позволяет вам изменить содержимое rezVector[0].first
, если вы действительно хотите это сделать. Но вы также можете присвоить результат rezVector[0].first
объекту типа char*
, так что вы получите копию ссылочного значения.
Так что я думаю, что выбор правильного типа зависит от того, что вы хотите сделать с результатом. Вы хотите изменить содержимое пары на месте или просто скопировать информацию?
См. Разницу в следующем примере:
int main() {
char val1[] = "Hello";
char val2[] = "World";
char val3[] = "out there";
vector<pair<char*, int> > rezVector; //is vector I'm using
rezVector.push_back({val1,10});
cout << "initial: " << rezVector[0].first << std::endl;
char*& tempPairFirstReadWrite = rezVector[0].first;
tempPairFirstReadWrite = val2;
cout << "changed: " << rezVector[0].first << std::endl;
char* tempPairFirstReadOnly = rezVector[0].first;
tempPairFirstReadOnly = val3;
cout << "not changed again: " << rezVector[0].first << std::endl;
}
Выход: [1111 ]
initial: Hello
changed: World
not changed again: World
Проанализируйте число в форму + N / (10^k), где a и N являются целыми числами, и k является количеством десятичных разрядов, которые Вы имеете.
Пример: 12.0345-> 12 + 345 / 10^4, = 12, N = 345, k = 4
Теперь, 10^k = (2 * 5) ^ k = 2^k * 5^k
Можно представить число как точную двоичную дробь, если и только если Вы избавляетесь от 5^k термин в знаменателе.
Результат проверил бы (N модификация 5^k) == 0
Это должно добиться цели:
bool isRepresentable(const char *realNumber)
{
double value = strtod(realNumber, NULL);
char test[20];
sprintf(test, "%f", value);
return strcmp(realNumber, test) == 0;
}
Вероятно, лучше всего для использования 'безопасной' версии sprintf для предотвращения потенциального переполнения буфера (это даже возможно в этом случае?)
Вот моя версия. sprintf преобразовывает 0.5 в 0,50000, нули в конце должны быть удалены.
Править: Должен быть переписан для обработки чисел без десятичной точки, которые заканчиваются 0 правильно (как 12 300).
bool isRepresentable( const char* realNumber ) { bool answer = false; double dVar = atof(realNumber); char check[20]; sprintf(check, "%f", dVar); // Remove zeros at end - TODO: Only do if decimal point in string for (int i = strlen(check) - 1; i >= 0; i--) { if (check[i] != '0') break; check[i] = 0; } answer = (strcmp(realNumber, check) == 0); return answer; }
Святая домашняя работа, денщик!:)
Что делает, это интересное - то, что Вы не можете просто сделать (atof|strtod|sscanf)-> sprintf цикл и проверять, вернули ли Вы исходную строку. sprintf на многих платформах обнаруживает "настолько близко, как Вы можете стать к 0,1" двойными и печатаете его как 0,1, например, даже при том, что 0.1 не является точно представимым.
#include <stdio.h>
int main() {
printf("%llx = %f\n",0.1,0.1);
}
печать: 3fb999999999999a = 0.100000
в моей системе.
Реальный ответ, вероятно, потребовал бы, чтобы парсинг двойное преобразовал его в точное дробное представление (0.1 = 1/10) и затем удостоверившись, что atof времена преобразования знаменатель равняются числителю.
Я думаю.
Преобразуйте строку в плавание с большим объемом, чем двойное. Бросок, что к двойному и видят, соответствуют ли они.
Я преобразовал бы строку в ее числовое разрядное представление, (немного массива или длинное), затем преобразовал бы строку в двойное и видел бы, соответствуют ли они.