Convert Double to LARGE_INTEGER

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

Convert Double to LARGE_INTEGER

Сообщение sosed213 » 08.04.2012 (Вс) 19:31

Здравствуйте.

Столкнулся с задачей:
Создаю раздел на жестком диске, где нужно указать размер тома в байтах, в виде LARGE_INTEGER.

Как преобразовывать из LARGE_INTEGER в Double нашел:
Код: Выделить всё
Private Function CLargeInt(Lo As Long, Hi As Long) As Double
    Dim dblLo As Double, dblHi As Double
    If Lo < 0 Then
        dblLo = 2 ^ 32 + Lo
    Else
        dblLo = Lo
    End If
   
    If Hi < 0 Then
        dblHi = 2 ^ 32 + Hi
    Else
        dblHi = Hi
    End If
    CLargeInt = dblLo + dblHi * 2 ^ 32
End Function


Вот как бы так этот алгоритм обратить?
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Convert Double to LARGE_INTEGER

Сообщение Хакер » 08.04.2012 (Вс) 20:40

Этого ни в коем случае нельзя делать. Во-первых не нужно, а во вторых — чрезвычайно опасно.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Convert Double to LARGE_INTEGER

Сообщение sosed213 » 08.04.2012 (Вс) 20:54

Ну а как тогда указывать размер разделов? (сори если глупый вопрос)


Вот накидал код, но не оптимизировал, на свежею голову переделаю.


Код: Выделить всё
Private Function Double2LI(Numeric As Double) As LARGE_INTEGER
   
    Dim n As Double
    n = (2 ^ 32) ' - 1
    If Numeric > n Then
        Dim n2 As Double
        Dim n3 As Double
        Dim n4 As Double
       
        n2 = Int(Numeric / n)
        n3 = n2 * n
        n4 = (Numeric - n3)
           
        Double2LI.highpart = n2
       
       
        If n4 = (2 ^ 31) Then
            n4 = -n4
        End If

        If n4 > (2 ^ 31) Then
            Double2LI.lowpart = n4 - n
        Else
            Double2LI.lowpart = n4
        End If
   
    ElseIf Numeric < n Then
        If Numeric < (2 ^ 31) Then
            Double2LI.lowpart = Numeric
        Else
            Double2LI.lowpart = Numeric - n
        End If
       
        Double2LI.highpart = 0
   
    ElseIf Numeric = n Then
        Double2LI.lowpart = 0
        Double2LI.highpart = 1
    End If
End Function



За то работает классно: cd.PartitionEntry(0).PartitionLength = Double2LI(37580963840#) '35GB
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Convert Double to LARGE_INTEGER

Сообщение Хакер » 08.04.2012 (Вс) 21:04

sosed213 писал(а):Ну а как тогда указывать размер разделов? (сори если глупый вопрос)

Я не знаю, что ответить, кроме как банальное «ну брать и указывать».

Давай пойдём от противного. На каком этапе и для чего потребовалось конвертировать размер раздела в Double?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Convert Double to LARGE_INTEGER

Сообщение sosed213 » 08.04.2012 (Вс) 21:09

Чтобы создать раздел на HDD надо в структуру DRIVE_LAYOUT_INFORMATION_EX занести кучу данных, в том числе StartingOffset и PartitionLength.
Эти два параметра объявлены как LARGE_INTEGER, и требуют указания в байтах. Дальше я думаю что все понятно, т.е. если указать 35 Gb то это получается 37580963840 байт, а это в lowpart и highpart просто так не запихнуть...
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Convert Double to LARGE_INTEGER

Сообщение Хакер » 08.04.2012 (Вс) 21:13

sosed213 писал(а):Чтобы создать раздел на HDD надо в структуру DRIVE_LAYOUT_INFORMATION_EX занести кучу данных, в том числе StartingOffset и PartitionLength.

Да. Но суть момента заключается в том, что туда надо заносить LARGE_INTEGER, а не Double. Double вообще не требуется использовать ни на одном из этапов. Ни на миг ни один из компонентов системы не требует указания чего бы то ни было в виде Double.


sosed213 писал(а):Дальше я думаю что все понятно

Нет!!!

Итак, задача: присвоить числу формата LARGE_INTEGER значение 37580963840. Вопрос на миллиард долларов: зачем тут Double?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Convert Double to LARGE_INTEGER

Сообщение sosed213 » 08.04.2012 (Вс) 21:18

Ну просто Double это 8-ми битное число, а целочисленное максимальное Это Long, но он всего 4-х битный.

Хакер, я знаю что ты заведомо знаешь ответ, и я уже понял что мой вариант, совсем не правильный.
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Convert Double to LARGE_INTEGER

Сообщение Хакер » 08.04.2012 (Вс) 21:23

sosed213 писал(а):Ну просто Double это 8-ми битное число, а целочисленное максимальное Это Long, но он всего 4-х битный.

Double это 64-битный, а Long — 32-битный.

sosed213 писал(а):Хакер, я знаю что ты заведомо знаешь ответ, и я уже понял что мой вариант, совсем не правильный.

Твоё решение — катастрофически неправильное. Оно входит в семейство тех программистских решений, благодаря которым люди получают смертельные дозы радиации, самолёты падают и взрываются ядерные реакторы. За исключением того, что ты не пишешь что-то столь же важное, хотя софт, работающий с разделами, это тоже очень ответственное дело. Потеря данных — локальная катастрофа.

Я знаю ответ. Он заключается в том, что Double ни на каком этапе не нужен, и нужно просто не использовать Double, потому что он не нужен.

По сути, ты говоришь: Long невмещает моё большое число, поэтому мне нужен Double. Блин! Нет же. Long не вмещает твои большие числа, поэтому тебе нужен не Double, а LARGE_INTEGER.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Convert Double to LARGE_INTEGER

Сообщение sosed213 » 08.04.2012 (Вс) 21:25

Тогда вопрос в следующем: как большое число записать в LARGE_INTEGER?
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Convert Double to LARGE_INTEGER

Сообщение Хакер » 08.04.2012 (Вс) 21:30

Тогда встречный вопрос: а в чём проблема?

Давай подумаем логически.
Есть переменная «foo» типа LARGE_INTEGER и нужно записать в неё большое число.
Очевидно, что это наше большое число может храниться только в другой переменной типа LARGE_INTEGER, например, в переменной «bar».

Тогда очень записать очень просто:
Код: Выделить всё
foo = bar
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение Qwertiy » 08.04.2012 (Вс) 21:34

sosed213 писал(а):и я уже понял что мой вариант, совсем не правильный.

Тоже считаю вариант с double не очень правильным, но не на столько.

Хакер писал(а):Этого ни в коем случае нельзя делать. Во-первых не нужно, а во вторых — чрезвычайно опасно.

Смотрим.
1. Double содержит 52 бита на мантиссу, значит в него можно без потери точности поместить значение от 1 до 2^53. 2^53 байт = 8192 ТБ - для раздела диска вполне достаточно.
2. Никто не задаёт значение в байтах, число скорее всего будет в мегабайтах, как минимум в килобайтах, что позволяет представить без потери точности значения на несколько порядков больше.
Так что ничего опасного в данном случае не вижу, а удобство работы с double по сравнению с парой кусков int64 достаточно очевидно.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Convert Double to LARGE_INTEGER

Сообщение Хакер » 08.04.2012 (Вс) 21:36

Qwertiy, вот обязательно ломать правильный ход дискуссии? :)
Можно же подождать до момента истины, и потом высказаться о своём мнении?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение Qwertiy » 08.04.2012 (Вс) 21:37

Хакер писал(а):Очевидно, что это наше большое число может храниться только в другой переменной типа LARGE_INTEGER, например, в переменной «bar».

А по-моему, очевидно, что его вводит пользователь, скорее всего в TextBox...

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Convert Double to LARGE_INTEGER

Сообщение sosed213 » 08.04.2012 (Вс) 21:38

Хакер писал(а):Очевидно, что это наше большое число может храниться только в другой переменной типа LARGE_INTEGER


Не совсем так, число чаще всего будет вводиться с клавиатуры, например 35 (т.е. 35 gb), затем это число нужно перевести в байты, а потом уже в LARGE_INTEGER.
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

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

Сообщение Qwertiy » 08.04.2012 (Вс) 21:41

Хакер писал(а):Quertiy, вот обязательно ломать правильный ход дискуссии? :)
Можно же подождать до момента истины, и потом высказаться о своём мнении?

Когда я начал писать ответ, этого хода тут ещё не было :) Последним было то сообщение sosed213'а, которое я процитировал.

PS: Я тоже не люблю, когда мой ник пишут неправильно ;)

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Convert Double to LARGE_INTEGER

Сообщение Хакер » 08.04.2012 (Вс) 21:43

sosed213 писал(а):Не совсем так, число чаще всего будет вводиться с клавиатуры, например 35 (т.е. 35 gb), затем это число нужно перевести в байты, а потом уже в LARGE_INTEGER.

Вот, наконец-то.
Значит истинная проблема состоит в том, чтобы написать функцию, которая переводит строчку с числом в LARGE_INTEGER число. Как видишь — Double вовсе не нужен.

Если более точно, нужно написать функцию, которая из последовательности символов, представляющих собой запись числа в некоторой системе счисления (в нашем случае — позиционной десятичной системе счисления) получасть само число.

Qwertiy писал(а):А по-моему, очевидно, что его вводит пользователь, скорее всего в TextBox...

Это типичная ошибка в рассуждениях. Пользователь вводит в TextBox не число, а строчку, являющуюся человеко-понятным представлением числа. И ещё не факт, что он введёт туда именно строчку, являющуюся человеко-понятным представлением числа, а не строчку «гы лол».
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение Qwertiy » 08.04.2012 (Вс) 21:46

sosed213 писал(а):затем это число нужно перевести в байты

Вот я тоже про такой ввод думал в начале.
Перевод в байты тут лишний шаг. Единица измерения по сути является битовым сдвигом, соответствующим образом её и надо обрабатывать. На мой взгляд, это будет самым правильным решением.
С другой стороны, я допускаю перевод в double для подсчёта чего-либо (я уже написал, почему).

Кстати, если бы VB поддерживал long double, то конвертирование в него из int64 всегда происходит без потери точности, если не ошибаюсь.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Convert Double to LARGE_INTEGER

Сообщение sosed213 » 08.04.2012 (Вс) 21:48

Мне кажется, есть отличный способ проверить, введено ли число:

If Trim(Text1.Text) = CStr(Val(Trim(Text1.Text))) Then

Это так, к текущему вопросу не относится.
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Convert Double to LARGE_INTEGER

Сообщение sosed213 » 08.04.2012 (Вс) 21:50

Qwertiy, а можно по подробней про битовый сдвиг, точнее про реализацию на VB.
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

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

Сообщение Qwertiy » 08.04.2012 (Вс) 21:50

Хакер писал(а):Это типичная ошибка в рассуждениях. Пользователь вводит в TextBox не число, а строчку, являющуюся человеко-понятным представлением числа. И ещё не факт, что он введёт туда именно строчку, являющуюся человеко-понятным представлением числа, а не строчку «гы лол».

В этой теме обсуждается, не как проверить находится ли в TextBox'е корректное представление размера, а как из корректного представления размера получить int64.
Я вообще NumericUpDown предпочитаю использовать. Он-то мне число обеспечит :)

Хакер писал(а):в нашем случае — позиционной десятичной системе счисления

Где же она позиционная, когда там в конце суффикс, означающий кратность?

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

Сообщение Qwertiy » 08.04.2012 (Вс) 21:53

sosed213 писал(а):Qwertiy, а можно по подробней про битовый сдвиг, точнее про реализацию на VB.

Мне кажется, в VB нет соответствующей операции в явном виде. Его можно заменить умножением/делением на соответствующую степень двойки.
Для того, чтобы не получить переполнение, надо предварительно выполнить соответствующий And.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Convert Double to LARGE_INTEGER

Сообщение Хакер » 08.04.2012 (Вс) 21:54

Нет, это наихудший способ проверить.

Серьёзно.
К сожалению, практически во всех языках этот функционал — невероятно убог, и задуман для архипримитивных приложений, баловства и начинающих программистов.

Дело заключается в том, что единственная функция, проверяющая правильность ввода числа, которая может считаться хорошей — эта функция, принимающая помимо строкового представления числа ещё кучу параметров.

Единственная функция, конвертирующая строковое представление числа в число, которая может считаться хорошей, — это функция, принимающая помимо строчки ещё и кучу параметров.

Функция StrToInt (не важно, как она в нашем языке называется: atoi или Val) — отстой, если только она не принимает вторым параметров информацию и системе счисления и куче разнообразных требований к преобразованию числу).
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение Qwertiy » 08.04.2012 (Вс) 21:55

sosed213 писал(а):If Trim(Text1.Text) = CStr(Val(Trim(Text1.Text))) Then

Хм... А если я +5 напишу?

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re:

Сообщение sosed213 » 08.04.2012 (Вс) 21:58

Qwertiy писал(а):
sosed213 писал(а):If Trim(Text1.Text) = CStr(Val(Trim(Text1.Text))) Then

Хм... А если я +5 напишу?


то будет просто 5
А если -5 , то будет -5

:)
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Convert Double to LARGE_INTEGER

Сообщение sosed213 » 08.04.2012 (Вс) 22:01

Нашел тут пост, о сравнении больших чисел

Пользователь arthur2 приводит код который тоже работает:

Код: Выделить всё
Private Function getLargeInteger(ByVal ValLargeInteger As Variant) As LARGE_INTEGER
  ValLargeInteger = CDec(ValLargeInteger)
 
  If ValLargeInteger > CDec("18446744073709551615") Then Err.Raise 6
  If ValLargeInteger < 0 Then Err.Raise 6
 
  CopyMemory getLargeInteger, ByVal VarPtr(ValLargeInteger) + 8, 8

End Function
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

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

Сообщение Qwertiy » 08.04.2012 (Вс) 22:02

sosed213 писал(а):то будет просто 5

Ага, получается поверка "+5" = "5", а это False :D

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re:

Сообщение sosed213 » 08.04.2012 (Вс) 22:03

Qwertiy писал(а):
sosed213 писал(а):то будет просто 5

Ага, получается поверка "+5" = "5", а это False :D



Хм, ага :)
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Convert Double to LARGE_INTEGER

Сообщение Хакер » 08.04.2012 (Вс) 22:11

sosed213 писал(а):Пользователь arthur2 приводит код который тоже работает:

Это тоже неправильный код в контексте твоего случая.

Единственный правильный в твоём случае код, это код, который пройдётся по строке и на основании этого сам заполнит поля LARGE_INTEGER-а. Без всяких там Val и CDec.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Convert Double to LARGE_INTEGER

Сообщение sosed213 » 08.04.2012 (Вс) 22:22

Спасибо вам огромное за помощь, выручаете уже не первый раз!
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Convert Double to LARGE_INTEGER

Сообщение Хакер » 08.04.2012 (Вс) 22:35

Есть опасение, что (судя по твоему последнему посту) ты намерен применить одно из плохих решений, которые ты привёл. Особенно с учётом того, что ты сторонник философии «какой код нашёл, такой и использую, пока не найду варианта получше».
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

След.

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

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 25

    TopList  
cron