|  | 
	| 
			| 
					
						| Olegator | 
								|  | « Ответ #1 : 20-12-2004 19:03 »  |  | 
 
 С помощью цикла с постусловием делишь на 10.0 до тех пор пока число не станет < 1.
 double n;
 do
 n=n/10.0;
 while (n>=1);
 printf("%lf",n)
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	|  | 
	| 
			| 
					
						| nikedeforest | 
								|  | « Ответ #3 : 20-12-2004 22:06 »  |  | 
 
 Вот может такая идейка подойдет, код конечно можно оптимизировать, это на скорую руку, также можно менять коэффициент но которе происходит сдвиг (самое главное-это смысл    ) #include <stdio.h>#include <conio.h>
 void main ()
 {
 clrscr();
 double point;
 double koef=10,s=1;
 printf("input point");
 scanf("%lf",&point);
 
 do
 {
 s=1;
 if(point<0.1)
 {
 for(int i=0; point<0.1;i++,s*=10)
 {point*=koef*s;}
 }
 //////////////
 s=1;
 if(point>1)
 {
 for(int i=0; point>1;i++,s*=100)
 {point/=koef*s;}
 }
 }
 while(!(point<1&&point>0.1));
 cout<<"\n"<<point;
 return;
 }
 
Выводит число не целиком, но на самом деле, там то что надо, в инспекторе можешь посмотреть. |  
						| 
								|  |  
								| « Последнее редактирование: 03-12-2007 17:24 от Алексей1153++ » |  Записан | 
 
 ещё один вопрос ... |  |  | 
	| 
			| 
					
						| Alf 
								Гость
 | 
								|  | « Ответ #4 : 20-12-2004 22:33 »  |  | 
 
 Если можно пользоваться операциями взятия логарифма и возведения в степень, без которых вряд ли обходится любая библиотека стандартных математических функций, то решить подобную задачу несложно.
 В данном примере:
 
 1. Берем исходное число - 123781344664681
 2. Вычисляем его логарифм по основанию 10:
 Log10(123781344664681) = 14.09265519622138561074672569222
 (разумеется, такая точность здесь излишня, я просто копирую результат из штатного калькулятора Windows).
 3. Берем целую часть логарифма (14) и прибавляем 1, получаем 15.
 4. Делим исходное число на 10 в степени 15, получаем:
 123781344664681/(10^15) = 0.123781344664681
 
 В общем случае, если исходное число X, искомое число Y определяется формулой:
 
 Y = X / (10 ^ (INT(LOG10(X)) + 1)),
 где
 ^ - операция возведения в степень,
 INT - функция взятия целой части числа,
 LOG10 - логарифм числа по основанию 10.
 
 Поскольку компы без математического сопроцессора уже канули в Лету, думаю, такая конструкция будет работать поэффективнее деления в цикле при достаточно большом значении X.
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| LEON 
								Гость
 | 
								|  | « Ответ #5 : 21-12-2004 10:42 »  |  | 
 
 А если число перевести в строку, слева дописать 0. и обратно в double? |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| nikedeforest | 
								|  | « Ответ #6 : 21-12-2004 14:25 »  |  | 
 
 Из double в string(Delphi) или в char (С) перевести нельзя.  |  
						| 
								|  |  
								|  |  Записан | 
 
 ещё один вопрос ... |  |  | 
	| 
			| 
					
						| nikedeforest | 
								|  | « Ответ #7 : 21-12-2004 14:26 »  |  | 
 
 Из double в string(Delphi) или в char (С) перевести нельзя.  |  
						| 
								|  |  
								|  |  Записан | 
 
 ещё один вопрос ... |  |  | 
	| 
			| 
					
						| Alf 
								Гость
 | 
								|  | « Ответ #8 : 21-12-2004 14:56 »  |  | 
 
 Из double в string(Delphi) или в char (С) перевести нельзя. 
 Посредством sprintf  можно. Только очень сомнительно, что окажется эффективнее вычисления логарифма при большом количестве значащих цифр. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| nikedeforest | 
								|  | « Ответ #9 : 21-12-2004 15:32 »  |  | 
 
 На сколько я помню, функция printf выводит числа ограниченной длины, там не больше 6 символов, если я не ошибаюсь. Интересно, на sprintf такие ограничения распространяются
 |  
						| 
								|  |  
								|  |  Записан | 
 
 ещё один вопрос ... |  |  | 
	| 
			| 
					
						| npak | 
								|  | « Ответ #10 : 21-12-2004 15:54 »  |  | 
 
 на печать выводится любое количество знаков, это можно настроить в строке формата.
 Непонятно другое -- что делать с этим дальше?  Ну получится строка "1,234567890123456e+78", и что?  надо разбирать строку, выделять мантиссу и показатель,  потом мантиссу переводить в число.  Но при этом число изменится -- либо часть знаков потеряется из-за недостаточной точности, либо новые получатся, если точность печати превышает точность мантиссы.  нехорошо и то, и другое.
 
 Я думаю, что десятичный логарифм -- наиболее подходящее решение.
 |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| Mfcer__ 
								Команда клуба
								
								   Offline | 
								|  | « Ответ #11 :  21-12-2004 23:52 »   |  | 
 
    double a = 12812896757;    int po = ((int)log10(a))   +1;    cout << po  << endl;    double val = pow(10,po);    cout << val << endl;    printf("%lf",a/val);    a /= val;    if ( a == 0.12812896757  ) // это условие не срабатывает, а на экран выводиться всякий бред...      cout << "Asasfaf" << endl; |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| maa | 
								|  | « Ответ #12 : 22-12-2004 04:31 »  |  | 
 
 У меня твой код великолепно отработал.Компилятор - Visual C++ 6.0.
 Добавил только инклюды и main () {...}
 
 #include <math.h>
 #include <iostream.h>
 #include <stdio.h>
 
 
 |  
						| 
								|  |  
								| « Последнее редактирование: 22-12-2004 04:33 от maa » |  Записан | 
 |  |  | 
	| 
			| 
					
						| Alf 
								Гость
 | 
								|  | « Ответ #13 : 22-12-2004 07:50 »  |  | 
 
 ...    if ( a == 0.12812896757 ) // это условие не срабатывает, а на экран выводиться всякий бред...      cout << "Asasfaf" << endl;Выбрось это условие и поставь вместо него безусловную печать значения a . Ни в коем случае нельзя сравнивать величины типа double  и float  на равенство, а тем более с литеральной константой. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| PSD 
								Главный специалист    Offline 
								Пол:    | 
								|  | « Ответ #14 : 22-12-2004 08:31 »  |  | 
 
 А идея просто забить эхпоненту нулями не подходит? |  
						| 
								|  |  
								| « Последнее редактирование: 22-12-2004 08:34 от PSD » |  Записан | 
 
 Да да нет нет все остальное от лукавого. |  |  | 
	| 
			| 
					
						| Mfcer__ 
								Команда клуба
								
								   Offline | 
								|  | « Ответ #15 : 22-12-2004 11:06 »  |  | 
 
 А идея просто забить эхпоненту нулями не подходит?
 Это как ? Можно поподробнее...  |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| PSD 
								Главный специалист    Offline 
								Пол:    | 
								|  | « Ответ #16 : 22-12-2004 12:18 »  |  | 
 
 Точно не скажу но из курса ПТЦА помню что числа сплавующей точкой хранятся в формате +|Мантиса|+|экспанента
 (в каком порядке  они лежат в double не знаю, поищи в MSDN)
 Причем мантиса всегда хранится в нормализованом виде те  0.123456
 если эти правила дествуют и для типа double  то для того чтобы из  12323456787 получить
 0.12323456787 достаточно зделать экспаненту раной 1.Для формата double  это заменить 12 бит на константу. Только я не уверен что  число там нормализованное...
 
 |  
						| 
								|  |  
								|  |  Записан | 
 
 Да да нет нет все остальное от лукавого. |  |  | 
	| 
			| 
					
						| Pu 
								Большой босс    Offline 
								78
								
								
								
								
								
							 | 
								|  | « Ответ #17 : 24-12-2004 08:24 »  |  | 
 
 в каком порядке лежат написано и нарисовано очень понятно здесь - http://www.sibsutis.ru/~mavr/MP/cod.htm |  
						| 
								|  |  
								|  |  Записан | 
 
 Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.(с) Артур Джонс
 |  |  | 
	| 
			| 
					
						| pilpilon 
								Гость
 | 
								|  | « Ответ #18 : 25-12-2004 15:32 »  |  | 
 
 #include <iostream> #include <iomanip> #include <sstream>  using namespace std; string mant ( double); double input_double(); int main() {  cout << "mant = " <<    mant(input_double()) << endl;  return 0; } string mant ( double arg ) {   ostringstream os;   os <<"  " << fixed <<          setprecision(24) <<            arg << endl;   int pointpos = os.str().find('.');    os.seekp(0);   os << "0.";   return os.str().erase(pointpos,1).substr(0,26); }    double input_double() {    double arg = .0;     cout << "enter double number" << endl;     cin >> arg;    return arg; } задаснка не столько про double , сколько про манипуляцию строками. А вот выгрызать мантиссу -- точно не будет работать нигде, кроме компьютера на котором скомпилировано    ю |  
						| 
								|  |  
								| « Последнее редактирование: 20-12-2007 20:34 от Алексей1153++ » |  Записан | 
 |  |  | 
	| 
			| 
					
						| PSD 
								Главный специалист    Offline 
								Пол:    | 
								|  | « Ответ #19 : 27-12-2004 06:50 »  |  | 
 
 задаснка не столько про double , сколько про манипуляцию строками. А вот выгрызать мантиссу -- точно не будет работать нигде, кроме компьютера на котором скомпилировано    юОбоснуй почему не будет работать? Я предпологал я то это должно работать как минимум на всем семействе 80х86! |  
						| 
								|  |  
								|  |  Записан | 
 
 Да да нет нет все остальное от лукавого. |  |  | 
	| 
			| 
					
						| pilpilon 
								Гость
 | 
								|  | « Ответ #20 : 27-12-2004 15:54 »  |  | 
 
 Ты хочешь сказать, что длина <double> на машинах 80х86 никогда не менялась ? и не будет? и что формат <double> универсален для процессора, а не , например, операционной системы / компилятора ?  что мантисса всегда нормализована?
 Кроме того, в общем случае это не сильно эффективно. Ну есть у тебя число 12345678912345678. ну выгрыз ты его мантиссу ...
 получил, допустим, битовое представление числа 12345678912345678 ( допустм оно все в мантиссу влезло) - эту радость все равно надо хотя бы в < long>  перевести, а еще потом делить...
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| PSD 
								Главный специалист    Offline 
								Пол:    | 
								|  | « Ответ #21 : 28-12-2004 06:01 »  |  | 
 
 Ты не прав в первом но прав во втором:По логике вещей тип добл обязан быть доинаков в рамках всего семества 80х86 как и все другие типы данных иначе старые программы просто бы не работали...  первая констаната типа доубл похерела работу прораммы на камне использующем другой формат...
 
 По второму вопросу ты прав я не учел что 9 и 0.9 имеют разню мантису....
 
 
 |  
						| 
								|  |  
								|  |  Записан | 
 
 Да да нет нет все остальное от лукавого. |  |  | 
	| 
			| 
					
						| baldr | 
								|  | « Ответ #22 : 28-12-2004 08:10 »  |  | 
 
 Я уже не понимаю про что тут спор. Ноги растут из перевода в строку а потом обратно? Это ж бред. По-моему давным-давно Alf дал единственно верный и лучший вариант. За что ему плюс.   |  
						| 
								|  |  
								|  |  Записан | 
 
 Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично |  |  | 
	| 
			| 
					
						| pilpilon 
								Гость
 | 
								|  | « Ответ #23 : 28-12-2004 13:22 »  |  | 
 
 Зависит от того, что надо сделать с результатом. Если вывести на печать, то надо один раз перевести в строчку и дальше работать с ней - будет всяко быстрей. Если же от результата нужно взять арксинус -- другое дело. (Но тогда не важно, как число записывается, важно, чему оно примерно равно). Тут <Alf> все правильно написал, ( хотя как быстро вычисляться будет< val/pow(10.0 , ceil( log10( val ) ) ) >  я судить не берусь, если повезет , то очень быстро, если нет - может и медленней, чем со строчкой.
 
 Я в основном  имел в виду , что в <C++> можно перевести <double> в <string>, причем так, как душе угодно, операция это эффективная и бояться ее не надо ( в тех случаях когда именно это и нужно)
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	|  |