50!
- 30414093201713378043612608166064768844377641568960512000000000000
или около 3.04e+64
, 215-битное число. Это значение обычно превышает диапазон типов, например long
. Даже uintmax_t
и unsigned long long
необходимо только иметь возможность представлять по меньшей мере 64-битные целые числа.
long int fact(long int n) {
...
// Overflows!
return n*fact(n-1);
Чтобы получить точный ответ, код может использовать альтернативные типы. Следующее использует строковое / десятичное представление целого числа. Он работает при больших значениях n
, так как правильная функциональность ограничена размером буфера.
char *strfact_mult(char *s, unsigned x) {
unsigned sum = 0;
size_t len = strlen(s);
size_t i = len;
while (i > 0) {
sum += (s[--i] - '0')*x;
s[i] = sum%10 + '0';
sum /= 10;
}
while (sum) {
len++;
memmove(&s[1], s, len);
s[i] = sum%10 + '0';
sum /= 10;
}
return s;
}
char *str_fact(char *dest, unsigned n) {
strcpy(dest, "1");
while (n > 1) {
strfact_mult(dest, n--);
}
return dest;
}
int main(void) {
char buf[1000];
puts(str_fact(buf, 0));
puts(str_fact(buf, 1));
puts(str_fact(buf, 5));
puts(str_fact(buf, 50));
}
Выход
1
1
120
30414093201713378043612608166064768844377641568960512000000000000
JNI имеет GetStringChars () функция также. Тип возврата является константой jchar*, jchar является 16-разрядным на win32 настолько способом, который был бы совместим с wchar_t. Не уверенный, если это - реальный UTF-16 или что-то еще...
Портативное и надежное решение состоит в том, чтобы использовать iconv с пониманием, что необходимо знать что кодирование системы wchar_t
использование (UTF-16 в Windows, UTF-32 во многих системах Unix, например).
Если Вы хотите минимизировать свою зависимость от стороннего кода, Вы можете также ручная самокрутка UTF-8 Ваш собственный преобразователь. Это легко при преобразовании в UTF-32, несколько тяжелее с UTF-16, потому что необходимо обработать суррогатные пары также.:-P Кроме того, необходимо стараться отклонить несамые короткие формы, или это может открыть ошибки безопасности в некоторых случаях.
Если мы не интересуемся кросс-платформенной способностью, окнами можно использовать функцию MultiByteToWideChar или полезные макросы A2W (касательно примера).
Просто используйте env-> GetStringChars (myString, 0); Java передает Unicode по своей природе
Я знаю, что этот вопрос был задан год назад, но мне не нравятся другие ответы, поэтому я все равно отвечу. Вот как мы это делаем в нашем источнике:
wchar_t * JavaToWSZ(JNIEnv* env, jstring string)
{
if (string == NULL)
return NULL;
int len = env->GetStringLength(string);
const jchar* raw = env->GetStringChars(string, NULL);
if (raw == NULL)
return NULL;
wchar_t* wsz = new wchar_t[len+1];
memcpy(wsz, raw, len*2);
wsz[len] = 0;
env->ReleaseStringChars(string, raw);
return wsz;
}
РЕДАКТИРОВАТЬ : Это решение хорошо работает на платформах, где wchar_t составляет 2 байта, некоторые платформы имеют 4 байта wchar_t, и в этом случае это решение не будет работать.
А кто освобождает wsz? Я бы рекомендовал STL!
std::wstring JavaToWSZ(JNIEnv* env, jstring string)
{
std::wstring value;
if (string == NULL) {
return value; // empty string
}
const jchar* raw = env->GetStringChars(string, NULL);
if (raw != NULL) {
jsize len = env->GetStringLength(string);
value.assign(raw, len);
env->ReleaseStringChars(string, raw);
}
return value;
}