Не все числовые константы можно записать символьно???

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Не все числовые константы можно записать символьно???

Сообщение Mikle » 26.03.2012 (Пн) 9:01

Выполните это:
Код: Выделить всё
  Dim a As Single
  Dim b As Single
 
  a = 1
  b = 3
  a = a / b
  MsgBox a
  MsgBox a = 0.3333333!

Какое точно значение записано в "a"?

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Не все числовые константы можно записать символьно???

Сообщение alibek » 26.03.2012 (Пн) 11:00

Mikle, не ждал этого от тебя.
Кто же сравнивает на равенство числа с плавающей запятой?
Выведи в бинарный файл (через put) значение переменной a=1/3 и переменной b=0.3333333!
Они будут различны.
Lasciate ogni speranza, voi ch'entrate.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Не все числовые константы можно записать символьно???

Сообщение alibek » 26.03.2012 (Пн) 11:07

Код: Выделить всё
Private Type tSingle
  v As Single
End Type

Private Type tDump
  b1 As Byte
  b2 As Byte
  b3 As Byte
  b4 As Byte
End Type

Private Sub Form_Load()
Dim v1 As tSingle, v2 As tSingle
Dim d1 As tDump, d2 As tDump
v1.v = 1 / 3
v2.v = 0.3333333!
LSet d1 = v1
LSet d2 = v2
Debug.Print v1.v, v2.v, v1.v = v2.v
Debug.Print "0x" & Right$("00" & Hex$(d1.b1), 2) & Right$("00" & Hex$(d1.b2), 2) & Right$("00" & Hex$(d1.b3), 2) & Right$("00" & Hex$(d1.b4), 2), _
            "0x" & Right$("00" & Hex$(d2.b1), 2) & Right$("00" & Hex$(d2.b2), 2) & Right$("00" & Hex$(d2.b3), 2) & Right$("00" & Hex$(d2.b4), 2)
End Sub

Код: Выделить всё
0.3333333     0.3333333    False
0xABAAAA3E    0xAAAAAA3E
Lasciate ogni speranza, voi ch'entrate.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 26.03.2012 (Пн) 11:17

Код: Выделить всё
MsgBox(a = 0.333333343!)
Дальше что?

alibek писал(а):Кто же сравнивает на равенство числа с плавающей запятой?

Ну, иногда можно сравниватьть, если вычислений нет, например...

Я бы спросил, зачем вообще в Single считать :)

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Не все числовые константы можно записать символьно???

Сообщение Mikle » 26.03.2012 (Пн) 12:11

Qwertiy писал(а):Я бы спросил, зачем вообще в Single считать

То же самое возможно и в Double, хотя не проверял.
alibek писал(а): не ждал этого от тебя.
Кто же сравнивает на равенство числа с плавающей запятой?

Я знаю, что никакие простые дроби, имеющие в знаменателе не степень двойки, не могут быть точно представлены в двоичном float point формате. Дело не в сравнении, а в том, что у некоторых чисел нет своей записи.
Qwertiy писал(а):Дальше что?

Я добавил твой MsgBox за своим, среда его АВТОМАТИЧЕСКИ превратила в "MsgBox a = 0.3333333!". Получилось:
Код: Выделить всё
  Dim a As Single
  Dim b As Single
 
  a = 1
  b = 3
  a = a / b
  MsgBox a = 0.3333333!
  MsgBox a = 0.3333333!

Первый MsgBox даёт False, а второй True. Согласитесь, это некрасиво, трудно было оставить ещё один символ в записи?
Далее я выделяю этот код, делаю "Cut", потом "Paste". С виду ничего не поменялось, но теперь ОБА MsgBox дают False.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Не все числовые константы можно записать символьно???

Сообщение alibek » 26.03.2012 (Пн) 12:49

Mikle писал(а):Согласитесь, это некрасиво, трудно было оставить ещё один символ в записи?

Не трудно, а невозможно.
Дробь 1/3 не может быть представлена конечным числом ни в десятичном, ни в двоичном виде.
Когда ты это число записываешь в десятичной системе — это одно округление, когда компьютер вычисляет его в двоичной системе — это другое округление.
Ну а фокус с 0.333333343! работает потому, что код программы VB не хранит в исходном виде.
Сохрани проект и открой заново, оба msgbox дадут один результат (либо в сохраненном исходнике у них будут разные значения).
Lasciate ogni speranza, voi ch'entrate.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Не все числовые константы можно записать символьно???

Сообщение Mikle » 26.03.2012 (Пн) 12:53

alibek писал(а):Дробь 1/3 не может быть представлена конечным числом ни в десятичном, ни в двоичном виде.

Я об этом писал:
Mikle писал(а):простые дроби, имеющие в знаменателе не степень двойки, не могут быть точно представлены в двоичном float point формате

Можно было добавить ещё одну значащую цифру, чтобы разным числам соответствовала разная запись, и чтобы преобразования bin->dec и dec->bin были однозначны (нет, не точны), не более того.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Не все числовые константы можно записать символьно???

Сообщение alibek » 26.03.2012 (Пн) 13:20

Mikle писал(а):Можно было добавить ещё одну значащую цифру, чтобы разным числам соответствовала разная запись, и чтобы преобразования bin->dec и dec->bin были однозначны (нет, не точны), не более того.

Single — это 8 (примерно) значащих разрядов, откуда возьмется еще один разряд?
Случай с 0.33333333! — это не девятый разряд, а разница в ошибках округления двоичного и десятичного представления числа.
Если ты числовые константы будешь записывать в двоичном представлении, подобных ошибок не будет.
Lasciate ogni speranza, voi ch'entrate.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Не все числовые константы можно записать символьно???

Сообщение Mikle » 26.03.2012 (Пн) 14:06

Single число результат деления 1/3 равно 0.333333343267441, ближайшее к нему Single число в большую сторону равно 0.333333373069763, следующее - 0.333333402872086 то есть хватило бы ещё одного знака для однозначного соответствия между числами и их записью:
0.33333334
0.33333337
0.3333334

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 26.03.2012 (Пн) 19:32

Mikle писал(а):Первый MsgBox даёт False, а второй True.

:lol: :lol: :lol: :lol: :lol: :lol: :lol:
Как хорошо, что я на VB.NET писал :D Просто скопировал константу из Watch и всё работает :)


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot, Google-бот и гости: 65

    TopList