Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Теоретические вопросы _ Форматированный вывод

Автор: MeatCrash 8.04.2006 8:38

Вот запись:
write(a:b:c);
где a - переменная
b,c - выражения тип integer, необязательные параметры, указывающие соответственно ширину выводимого поля и количество дробных цифр.

С a и c всё понятно, а вот b просто заводит меня в тупик, дело в том, что если b имеет значение 1, то до дробной части можно писать ещё порядка 15 знаков, но ведь b должно в этом меня ограничивать, так? А этого не происходит. Почему? Заранее спасибо за ответ на тупой вопрос. unsure.gif

Автор: klem4 8.04.2006 12:50

Вот тебе пример программы, надеюсь он поможет тебе разобраться :

uses crt;
var
i : integer;

begin
clrscr;
for i := 1 to 10 do writeln('pi : ',pi : i : 1);
readln;
end.


Как только i становится больше длины выводимого выражение (в данном случае 3.1 (3 символа)) то места под мантису выделяется больше и за счет лишей позиции проиходит сдвиг, а пока их нет, все печатается на одном месте, вот и все.

Первый параметр - это МИНИМАЛЬНОЕ кол-во позиций, выделяемых под число.

Автор: MeatCrash 9.04.2006 5:32

Спасибо! Уже начинает доходить... lol.gif Про пробелы я в принципе я так и думал, но! Интересен сам факт того, что даже если эту 1-цу оставить, то написать 15 символов можно, но 16 опять же затрёт дробную часть. Мне вот это теперь надо понять, а то получается, что эта опция живёт по своим, никому не виданным правилам. Заранее спасибо за ответ.

Автор: volvo 9.04.2006 5:52

Цитата(MeatCrash @ 9.04.2006 1:32)
Интересен сам факт того, что даже если эту 1-цу оставить, то написать 15 символов можно, но 16 опять же затрёт дробную часть. Мне вот это теперь надо понять

А нам надо понять, что ты имеешь в виду!!! Тебе привели код, по которому ты начал что-то понимать? Будь добр привести СВОЙ код, в котором ты хочешь разобраться!

Автор: MeatCrash 9.04.2006 6:29

И не зачем так кричать...

Program Simply_plane;
Var
a,b:real;

begin
a:=12345678901234567890.345;
b:=1234567890.972;
writeln('a=',a:1:2);
writeln('b=',b:1:2);
readln;
end.

Если сделать 10 символов до точки, то дробная часть 34 ещё будет видна, а если так и оставить 20 символов, то она затрётся. Почему? Ведь я поставил разрешение ввода строки всего на 1 символ, то есть паскаль вообще должен писать только 1 символ. Сейчас я понятно изъяснился? Если да, то ответь на мой вопрос, пожалуйста.

Автор: volvo 9.04.2006 6:35

Твоя программа просто не будет выводить ни в каком виде. Она просто напросто не откомпилируется. Можешь проверить... Во-первых, ты забыл слово Var, во-вторых, в целое (Integer) число НЕЛЬЗЯ заносить вещественное значение, ну и в третьих, число типа Integer способно принимать значения от -32768 до 32767

Так что вопрос остался открытым: как именно затирается дробная часть.

Автор: MeatCrash 9.04.2006 6:56

Цитата(volvo @ 9.04.2006 5:35) *

Твоя программа просто не будет выводить ни в каком виде. Она просто напросто не откомпилируется. Можешь проверить... Во-первых, ты забыл слово Var, во-вторых, в целое (Integer) число НЕЛЬЗЯ заносить вещественное значение, ну и в третьих, число типа Integer способно принимать значения от -32768 до 32767

Так что вопрос остался открытым: как именно затирается дробная часть.

Сейчас всё починил. Ну новичок я. Что с меня взять? rolleyes.gif Теперь нормально? Дробная часть становится равной нулю, примерно такой вид: 12345678901000000000.00. Понятно?

Автор: volvo 9.04.2006 7:43

Цитата(MeatCrash @ 9.04.2006 2:56)
Сейчас всё починил. Ну новичок я. Что с меня взять? rolleyes.gif Теперь нормально? Дробная часть становится равной нулю, примерно такой вид: 12345678901000000000.00. Понятно?

Продолжаем краткую экскурсию в систему типов языка:
Здесь проблема совершенно не в том, сколько чисел ТЫ разрешил печатать при выводе. Проблема вот в чем. Любое вещественное число в памяти компьютера представляется в виде мантиссы (нормализованной) и экспоненты, то есть число 12345.6 будет храниться в виде 1.23456 * 10^4

Так вот, о проблеме - у переменных типа Real точность мантиссы ограничена 11 - 12 знаками, то есть все цифры, начиная с 12 от десятичной точки просто напросто теряются... Теперь более понятно, что происходит? Вот твой же пример:
12345678901234567890.345
нормализуем мантиссу и приводим число к экспоненциальному виду, как оно хранится в памяти:
1.2345678901234567890345 * 10^19 (можешь в этом убедиться в окне Watches)
теперь "теряем точность" - оставляем только первые 11 цифр после запятой:
1.2345678901200000000000 * 10^19

И вот это число ты печатаешь... А при печати с указанием ширины поля вывода кроме всего прочего происходит еще и округление. Что имеем? Число опять преобразуется из экспоненциальной в обычную форму, округляется по правилам математики до того количества цифр после запятой, что ты указал вторым параметром, и распечатывается:
12345678901200000000.00 (после запятой ставится столько цифр, сколько ты просил, а перед запятой программа ничего менять не имеет права, если заданное тобой первое поле БОЛЬШЕ чем есть цифр перед запятой, то как написал klem4, перед числом будут добавлены пробелы. Если же ты указал первое поле МЕНЬШЕ, чем есть цифр перед запятой, то число выведется полностью, но пробелы перед ним ставиться не будут)...

Теперь понятно, откуда это берется? Кстати, это не самая простая тема для начинающего... no1.gif Могу только добавить, что чуть-чуть поправить ситуацию можно, если использовать более емкие сопроцессорные типы: Double (15-16 значащих цифр) и Extended (19-20 значащих цифр). Но все равно, их точность тоже не безгранична, и даже 20 цифр - не так много...

Автор: APAL 9.04.2006 7:51

А может MeatCrash в бан? mad.gif

Цитата
Program Fucking_plane;

Нарушение правил п.1 пп.1 !

Автор: MeatCrash 9.04.2006 8:10

Цитата(volvo @ 9.04.2006 6:43) *
Теперь понятно, откуда это берется? Кстати, это не самая простая тема для начинающего...
Последнее предложение означает, что мне пока не надо в это соваться или ты это меня так похвалил? cool.gif

APAL, Ня надо. unsure.gif Я больше не буду. mega_chok.gif

Автор: volvo 9.04.2006 12:15

Последнее предложение означает: "не удивляйся, если ничего с этой темой не будет получаться, тебя еще ждут сюрпризы" smile.gif

Автор: MeatCrash 10.04.2006 7:39

Судя по моим знаниям их ещё будет немало. smile.gif

Автор: hydroxychloroquine zinc and zith 23.09.2021 15:47

Healthy Male Internet

Автор: gabapentin side effects weight g 10.10.2021 15:20

natural viagra cialis

Автор: azithromycin over the counter ca 19.12.2021 0:01

cialis non prescription