Rambler's Top100
Форум: MS ACCESSVBVBA MS OfficeMS SQL server
Новые сообщения: 0000

Форум: MS ACCESS

Вопросы связанные с MS ACCESS

Обновить визитку
Участники «Online»
Все участники

 
 

Доброго времени суток, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Побитовое умножение в Access-2003
 
 автор: May   (21.08.2009 в 09:22)   личное сообщение
 
 

Подскажите пожалуйста как перемножить побитово 2 числа.
Например есть Таблица1,с полями:

Поле1 Поле2 Желаемый результат
10101 100101 101
101 111 101
..... ....... ...........
Нашла только что побитовое умножение можно записать как AND (&)
Если пишу AND,то выдаёт либо нули,либо -1......если пишу &,то получается конкатенация.

  Ответить  
 
 автор: osmor   (21.08.2009 в 09:40)   личное сообщение
 
 

У вас поля наверняка текcтовые, а умножать можно только числа
10101 = 21
100101 = 37
? 21 and 37
5
5 = 101
переводите в десятичные, умножайте, переводите в двоичное
или напишите свою функцию, которая будет с текстом представляющим двоичное число работать

  Ответить  
 
 автор: May   (21.08.2009 в 10:09)   личное сообщение
 
 

Попробовала с десятичными.
Поле1 (=21) и Поле2(=37) числовые.
После того как пишу для Поля3 Выражение: [Поле1] AND [Поле2] выдаёт результат -1 (((

  Ответить  
 
 автор: ДрЮня   (21.08.2009 в 10:11)   личное сообщение
 
 

здесь AND не то, о чем Вы подумали :)

  Ответить  
 
 автор: May   (21.08.2009 в 10:14)   личное сообщение
 
 

Т.е. AND только просто как объединение? я просто не могу понять почему вообще -1
И как тогда надо?

  Ответить  
 
 автор: osmor   (21.08.2009 в 10:49)   личное сообщение
 
 

Просто в запросе не получится, поскольку AND в JET не выполняет умножение, в JET это логическая операция
поскольку любое число отличное от 0 интерпретируется как ИСТИНА, то
TRUE AND TRUE = TRUE
True в числовом представлении -1
по этому у вас и получается -1
что делать
вариант1
Написать свою функцию, примерно такую:

Public Function myAND(lnga As Long, lngB As Long) As Long
myAND = nz(lnga,0) And nz(lngB,0)
End Function

в запросе вызывать эту функцию

select filed1,filed2, myAND([field1],[field2]) as field1ANDfield2 from table1


вариант2
написать функцию которая будет работать непосредственно с текстовым представлением двоичного числа, (тоже довольно не сложно, но времени сейчас нет,) и тоже вызывать ее из запроса

  Ответить  
 
 автор: May   (21.08.2009 в 10:51)   личное сообщение
 
 

Большое спасибо))

  Ответить  
 
 автор: ShadowOfSun   (21.08.2009 в 11:17)   личное сообщение
 
 

А вот и функция

Public Function DecAnd(ByVal FirstNum As Long, SecondNum As Long) As String
   Dim FirstX As String
   Dim SecondX As String
   Dim i As Long
   
   Const StrAnd As String = " AND "
   Const StrEnd As String = " = "
   Const LenX As Long = 10 'Длинна строки
   DecAnd = String(LenX, "0")
   
   FirstX = ToBinary(FirstNum, LenX)
   SecondX = ToBinary(SecondNum, LenX)
   
   For i = 1 To LenX
      If Mid$(FirstX, i, 1) = Mid$(SecondX, i, 1) Then Mid$(DecAnd, i, 1) = Mid$(FirstX, i, 1)
   Next i
   DecAnd = FirstX & StrAnd & SecondX & StrEnd & DecAnd
End Function

Public Function ToBinary(ByVal Number As Long, Optional Digits As Long = 24) As String
    Dim Ret As String 'Created by Lucas
    Dim i As Long
    Const ZERO As String = "0"
    Const ONE As String = "1"
    Ret = String(Digits, ZERO)
    
    If Number Then
        For i = Digits To 0 Step -1
            If Number Mod 2 Then
                Mid$(Ret, i, 1) = ONE
            End If
            Number = Number \ 2
        Next i
    End If
    ToBinary = Ret
End Function

  Ответить  
 
 автор: May   (21.08.2009 в 11:44)   личное сообщение
 
 

Ой,спасибочки))))

  Ответить  
 
 автор: osmor   (21.08.2009 в 12:01)   личное сообщение
 
 

Не в качестве критики, просто соображения
Не проверял, но мне кажется с ведущими нулями будет проблема...
если в функцию передается Long может лучше сначала
FirstNum AND SecondNum
а уже потом результат в ToBinary
свое
For i = 1 To LenX
If Mid$(FirstX, i, 1) = Mid$(SecondX, i, 1) Then Mid$(DecAnd, i, 1) = Mid$(FirstX, i, 1)
Next i
имеет смысл только если в функцию передавать строки вида "100101"

  Ответить  
 
 автор: osmor   (21.08.2009 в 12:07)   личное сообщение
 
 

Предлагаю так:

Public Function DecAnd(ByVal FirstNum As Long, SecondNum As Long) As String
   Dim FirstX As String
   Dim SecondX As String
   Dim i As Long
   
   Const StrAnd As String = " AND "
   Const StrEnd As String = " = "
   Const LenX As Long = 10
   DecAnd = String(LenX, "0")
   
   FirstX = ToBinary(FirstNum)
   SecondX = ToBinary(SecondNum)
   
   DecAnd = ToBinary(FirstNum And SecondNum)
   
   'For i = 1 To LenX
   '   If Mid$(FirstX, i, 1) = Mid$(SecondX, i, 1) Then Mid$(DecAnd, i, 1) = Mid$(FirstX, i, 1)
   ' Next i
   DecAnd = FirstX & StrAnd & SecondX & StrEnd & DecAnd
End Function
Public Function ToBinary(ByVal Number As Long) As String
    ToBinary = Number Mod 2
    Do While Number > 0
        Number = Number \ 2
        ToBinary = ToBinary & Abs(Number Mod 2 > 0)
    Loop
    ToBinary = StrReverse(ToBinary)
    If Len(ToBinary) > 1 Then ToBinary = Mid(ToBinary, 2)
End Function

  Ответить  
 
 автор: ShadowOfSun   (21.08.2009 в 12:28)   личное сообщение
 
 

Блин, не описал
в функцию DecAnd передается в десятеричной системе
сразу преобразуется в двоичную,а затем обрабатывается

  Ответить  
 
 автор: May   (23.08.2009 в 09:03)   личное сообщение
 
 

А если мне нужно будет побитово перемножить не поля,а записи,то алгоритм останется тот же?

  Ответить  
 
 автор: ShadowOfSun   (23.08.2009 в 10:01)   личное сообщение
12 Кб.
 
 

Глянь на пример

  Ответить  
 
 автор: ShadowOfSun   (23.08.2009 в 10:11)   личное сообщение
 
 

Спасибо, osmor
что-то я слона то и не приметил
функция упрощается до

Public Function DecAnd(ByVal FirstNum As Long, SecondNum As Long, Optional LenX As Long = 24) As String
   DecAnd = ToBinary(FirstNum And SecondNum, LenX)
End Function

Для входных данных двоичной строкой


Public Function DecAndStr(ByVal FirstX As String, SecondX As String, Optional LenX As Long = 24) As String
   Dim i As Long
   DecAndStr = String(LenX, "0")
   
   FirstX = Mid$(DecAndStr & FirstX, Len(FirstX) + 1)
   SecondX = Mid$(DecAndStr & SecondX, Len(SecondX) + 1)
   
   For i = 1 To LenX
      If Mid$(FirstX, i, 1) = Mid$(SecondX, i, 1) Then Mid$(DecAndStr, i, 1) = Mid$(FirstX, i, 1)
   Next i
End Function


  Ответить  
HiProg.com - Технологии программирования
Rambler's Top100 TopList