Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/Разложить число на простые множители - Мир MS Excel

Старая форма входа
  • Страница 1 из 2
  • 1
  • 2
  • »
Модератор форума: китин  
Мир MS Excel » Работа и общение » Мозговой штурм » Разложить число на простые множители (VBA)
Разложить число на простые множители
MCH Дата: Воскресенье, 26.07.2015, 12:10 | Сообщение № 1
Группа: Админы
Ранг: Старожил
Сообщений: 2003
Репутация: 751 ±
Замечаний: ±

Задача для макрописцев.
Необходимо написать UDF, которое любое целое число от 2 до 2^31-1 раскладывала в виде произведения простых множителей.
Если число простое, то функция должна возвратить значение "Prime"

Например, число 12 это 2*2*3, число 2 147 483 600 это 2*2*2*2*5*5*173*31033, 2 147 483 645 это 5*19*22605091, а число 2 147 483 647 является простым
Необходимо написать достаточно быструю функцию, способную работать с большими числами, при этом желательно, чтобы она была лаконичной.

Примеры разложения некоторых чисел на множители - во вложении
К сообщению приложен файл: PrimeFact.xlsx (10.4 Kb)
 
Ответить
СообщениеЗадача для макрописцев.
Необходимо написать UDF, которое любое целое число от 2 до 2^31-1 раскладывала в виде произведения простых множителей.
Если число простое, то функция должна возвратить значение "Prime"

Например, число 12 это 2*2*3, число 2 147 483 600 это 2*2*2*2*5*5*173*31033, 2 147 483 645 это 5*19*22605091, а число 2 147 483 647 является простым
Необходимо написать достаточно быструю функцию, способную работать с большими числами, при этом желательно, чтобы она была лаконичной.

Примеры разложения некоторых чисел на множители - во вложении

Автор - MCH
Дата добавления - 26.07.2015 в 12:10
Светлый Дата: Воскресенье, 26.07.2015, 21:53 | Сообщение № 2
Группа: Друзья
Ранг: Старожил
Сообщений: 1829
Репутация: 510 ±
Замечаний: 0% ±

Excel 2013, 2016
Если формулой считать, то существует ограничение 2^20-1, это для 2007 - количество строк на листе.


Программировать проще, чем писать стихи.
 
Ответить
СообщениеЕсли формулой считать, то существует ограничение 2^20-1, это для 2007 - количество строк на листе.

Автор - Светлый
Дата добавления - 26.07.2015 в 21:53
Udik Дата: Воскресенье, 26.07.2015, 22:11 | Сообщение № 3
Группа: Друзья
Ранг: Старожил
Сообщений: 1588
Репутация: 192 ±
Замечаний: 0% ±

Excel 2016 х 64
Вроде ж написали
Задача для макрописцев.


Я составил с использованием доп. листа, чисто для наглядности. Упс, не озаботился насчёт Prime


вот вам барабан
яд 41001231307558 wm R419131876897
udik1968@gmail.com


Сообщение отредактировал Udik - Воскресенье, 26.07.2015, 22:14
 
Ответить
СообщениеВроде ж написали
Задача для макрописцев.


Я составил с использованием доп. листа, чисто для наглядности. Упс, не озаботился насчёт Prime

Автор - Udik
Дата добавления - 26.07.2015 в 22:11
Rioran Дата: Понедельник, 27.07.2015, 10:44 | Сообщение № 4
Группа: Авторы
Ранг: Ветеран
Сообщений: 903
Репутация: 290 ±
Замечаний: 0% ±

Excel 2013
Михаил, привет.

Предлагаю такой вариант. Во вложении.

[vba]
Код
Function MCH_F$(X&)
     Dim n1&, n2&, A(), j&, U&, Y&
     j = 0
     Select Case X
         Case 0 To 3, 5, 7
         MCH_F = "Prime"
         Exit Function
     End Select
     Do While X Mod 2 = 0
         ReDim Preserve A(j)
         A(j) = 2
         X = X / 2
         j = j + 1
     Loop
     Do While X Mod 3 = 0
         ReDim Preserve A(j)
         A(j) = 3
         X = X / 3
         j = j + 1
     Loop
     U = X \ 2
     n1 = 5
     n2 = 7
     Do While n1 < U
         Y = X
         Do While X Mod n1 = 0
             ReDim Preserve A(j)
             A(j) = n1
             X = X / n1
             j = j + 1
         Loop
         If X Mod n2 = 0 Then
             ReDim Preserve A(j)
             A(j) = n2
             X = X / n2
             j = j + 1
         End If
         If X <> Y Then
             U = X \ 2
         End If
         n1 = n1 + 6
         n2 = n1 + 2
     Loop
     If j = 0 Then
         MCH_F = "Prime"
     Else
         If X <> 1 Then
             ReDim Preserve A(j)
             A(j) = X
         End If
         MCH_F = Join(A, "*")
     End If
End Function
[/vba]
К сообщению приложен файл: MCH_F.xlsb (18.0 Kb)


Роман, Москва, voronov_rv@mail.ru
Яндекс-Деньги: 41001312674279
 
Ответить
СообщениеМихаил, привет.

Предлагаю такой вариант. Во вложении.

[vba]
Код
Function MCH_F$(X&)
     Dim n1&, n2&, A(), j&, U&, Y&
     j = 0
     Select Case X
         Case 0 To 3, 5, 7
         MCH_F = "Prime"
         Exit Function
     End Select
     Do While X Mod 2 = 0
         ReDim Preserve A(j)
         A(j) = 2
         X = X / 2
         j = j + 1
     Loop
     Do While X Mod 3 = 0
         ReDim Preserve A(j)
         A(j) = 3
         X = X / 3
         j = j + 1
     Loop
     U = X \ 2
     n1 = 5
     n2 = 7
     Do While n1 < U
         Y = X
         Do While X Mod n1 = 0
             ReDim Preserve A(j)
             A(j) = n1
             X = X / n1
             j = j + 1
         Loop
         If X Mod n2 = 0 Then
             ReDim Preserve A(j)
             A(j) = n2
             X = X / n2
             j = j + 1
         End If
         If X <> Y Then
             U = X \ 2
         End If
         n1 = n1 + 6
         n2 = n1 + 2
     Loop
     If j = 0 Then
         MCH_F = "Prime"
     Else
         If X <> 1 Then
             ReDim Preserve A(j)
             A(j) = X
         End If
         MCH_F = Join(A, "*")
     End If
End Function
[/vba]

Автор - Rioran
Дата добавления - 27.07.2015 в 10:44
Rioran Дата: Понедельник, 27.07.2015, 11:46 | Сообщение № 5
Группа: Авторы
Ранг: Ветеран
Сообщений: 903
Репутация: 290 ±
Замечаний: 0% ±

Excel 2013
Ограничил область перебираемых чисел, стало работать значительно быстрее.

[vba]
Код
Function MCH_F$(X&)
     Dim n1&, n2&, A(), j&, U&, Y&
     j = 0
     Select Case X
         Case 0 To 3, 5, 7
         MCH_F = "Prime"
         Exit Function
     End Select
     Do While X Mod 2 = 0
         ReDim Preserve A(j)
         A(j) = 2
         X = X / 2
         j = j + 1
     Loop
     Do While X Mod 3 = 0
         ReDim Preserve A(j)
         A(j) = 3
         X = X / 3
         j = j + 1
     Loop
     U = X \ 4
     n1 = 5
     n2 = 7
     Do While n1 < U
         Y = X
         Do While X Mod n1 = 0
             ReDim Preserve A(j)
             A(j) = n1
             X = X / n1
             j = j + 1
         Loop
         If X Mod n2 = 0 Then
             ReDim Preserve A(j)
             A(j) = n2
             X = X / n2
             j = j + 1
         End If
         U = X \ n2
         n1 = n1 + 6
         n2 = n1 + 2
     Loop
     If j = 0 Then
         MCH_F = "Prime"
     Else
         If X <> 1 Then
             ReDim Preserve A(j)
             A(j) = X
         End If
         MCH_F = Join(A, "*")
     End If
End Function
[/vba]
К сообщению приложен файл: MCH_F2.xlsb (18.0 Kb)


Роман, Москва, voronov_rv@mail.ru
Яндекс-Деньги: 41001312674279
 
Ответить
СообщениеОграничил область перебираемых чисел, стало работать значительно быстрее.

[vba]
Код
Function MCH_F$(X&)
     Dim n1&, n2&, A(), j&, U&, Y&
     j = 0
     Select Case X
         Case 0 To 3, 5, 7
         MCH_F = "Prime"
         Exit Function
     End Select
     Do While X Mod 2 = 0
         ReDim Preserve A(j)
         A(j) = 2
         X = X / 2
         j = j + 1
     Loop
     Do While X Mod 3 = 0
         ReDim Preserve A(j)
         A(j) = 3
         X = X / 3
         j = j + 1
     Loop
     U = X \ 4
     n1 = 5
     n2 = 7
     Do While n1 < U
         Y = X
         Do While X Mod n1 = 0
             ReDim Preserve A(j)
             A(j) = n1
             X = X / n1
             j = j + 1
         Loop
         If X Mod n2 = 0 Then
             ReDim Preserve A(j)
             A(j) = n2
             X = X / n2
             j = j + 1
         End If
         U = X \ n2
         n1 = n1 + 6
         n2 = n1 + 2
     Loop
     If j = 0 Then
         MCH_F = "Prime"
     Else
         If X <> 1 Then
             ReDim Preserve A(j)
             A(j) = X
         End If
         MCH_F = Join(A, "*")
     End If
End Function
[/vba]

Автор - Rioran
Дата добавления - 27.07.2015 в 11:46
MCH Дата: Понедельник, 27.07.2015, 19:47 | Сообщение № 6
Группа: Админы
Ранг: Старожил
Сообщений: 2003
Репутация: 751 ±
Замечаний: ±

Роман, твоя функция работает чуть быстрее моей (может быть за счет использования массива, я склеивал переменную). У меня функция строчек на 10-12.
Я так понимаю, что ты используешь решето Аткина?

У тебя сбоит на некоторых числах, например на 343 раскладывает как 7*49, а должно быть 7*7*7
 
Ответить
СообщениеРоман, твоя функция работает чуть быстрее моей (может быть за счет использования массива, я склеивал переменную). У меня функция строчек на 10-12.
Я так понимаю, что ты используешь решето Аткина?

У тебя сбоит на некоторых числах, например на 343 раскладывает как 7*49, а должно быть 7*7*7

Автор - MCH
Дата добавления - 27.07.2015 в 19:47
Rioran Дата: Понедельник, 27.07.2015, 19:56 | Сообщение № 7
Группа: Авторы
Ранг: Ветеран
Сообщений: 903
Репутация: 290 ±
Замечаний: 0% ±

Excel 2013
343 раскладывает как 7*49, а должно быть 7*7*7

Спасибо, что заметил, Михаил. Я в одном месте два If превращал в Do While, один превратил, а на втором заснул =) Поправил. Теперь всё норм, прикладываю.

[vba]
Код
Function MCH_F$(X&)
      Dim n1&, n2&, A(), j&, U&, Y&
      j = 0
      Select Case X
          Case 0 To 3, 5, 7
          MCH_F = "Prime"
          Exit Function
      End Select
      Do While X Mod 2 = 0
          ReDim Preserve A(j)
          A(j) = 2
          X = X / 2
          j = j + 1
      Loop
      Do While X Mod 3 = 0
          ReDim Preserve A(j)
          A(j) = 3
          X = X / 3
          j = j + 1
      Loop
      U = X \ 4
      n1 = 5
      n2 = 7
      Do While n1 < U
          Y = X
          Do While X Mod n1 = 0
              ReDim Preserve A(j)
              A(j) = n1
              X = X / n1
              j = j + 1
          Loop
          Do While X Mod n2 = 0
              ReDim Preserve A(j)
              A(j) = n2
              X = X / n2
              j = j + 1
          Loop
          U = X \ n2
          n1 = n1 + 6
          n2 = n1 + 2
      Loop
      If j = 0 Then
          MCH_F = "Prime"
      Else
          If X <> 1 Then
              ReDim Preserve A(j)
              A(j) = X
          End If
          MCH_F = Join(A, "*")
      End If
End Function
[/vba]
ты используешь решето Аткина?

Скорее нет, чем да. Алгоритм я придумывал сам. Я заметил, что при поиске простых чисел можно использовать шаги по 12 и уже от этого отталкивался. Но, так получилось, что с решетом Аткина есть сходство.

У меня функция строчек на 10-12.

Я что-то не сразу заметил, что это мозговой штурм =) Краткость в этот раз я принёс в жертву.
К сообщению приложен файл: MCH_F3.xlsb (17.4 Kb)


Роман, Москва, voronov_rv@mail.ru
Яндекс-Деньги: 41001312674279


Сообщение отредактировал Rioran - Понедельник, 27.07.2015, 19:57
 
Ответить
Сообщение
343 раскладывает как 7*49, а должно быть 7*7*7

Спасибо, что заметил, Михаил. Я в одном месте два If превращал в Do While, один превратил, а на втором заснул =) Поправил. Теперь всё норм, прикладываю.

[vba]
Код
Function MCH_F$(X&)
      Dim n1&, n2&, A(), j&, U&, Y&
      j = 0
      Select Case X
          Case 0 To 3, 5, 7
          MCH_F = "Prime"
          Exit Function
      End Select
      Do While X Mod 2 = 0
          ReDim Preserve A(j)
          A(j) = 2
          X = X / 2
          j = j + 1
      Loop
      Do While X Mod 3 = 0
          ReDim Preserve A(j)
          A(j) = 3
          X = X / 3
          j = j + 1
      Loop
      U = X \ 4
      n1 = 5
      n2 = 7
      Do While n1 < U
          Y = X
          Do While X Mod n1 = 0
              ReDim Preserve A(j)
              A(j) = n1
              X = X / n1
              j = j + 1
          Loop
          Do While X Mod n2 = 0
              ReDim Preserve A(j)
              A(j) = n2
              X = X / n2
              j = j + 1
          Loop
          U = X \ n2
          n1 = n1 + 6
          n2 = n1 + 2
      Loop
      If j = 0 Then
          MCH_F = "Prime"
      Else
          If X <> 1 Then
              ReDim Preserve A(j)
              A(j) = X
          End If
          MCH_F = Join(A, "*")
      End If
End Function
[/vba]
ты используешь решето Аткина?

Скорее нет, чем да. Алгоритм я придумывал сам. Я заметил, что при поиске простых чисел можно использовать шаги по 12 и уже от этого отталкивался. Но, так получилось, что с решетом Аткина есть сходство.

У меня функция строчек на 10-12.

Я что-то не сразу заметил, что это мозговой штурм =) Краткость в этот раз я принёс в жертву.

Автор - Rioran
Дата добавления - 27.07.2015 в 19:56
MCH Дата: Понедельник, 27.07.2015, 21:16 | Сообщение № 8
Группа: Админы
Ранг: Старожил
Сообщений: 2003
Репутация: 751 ±
Замечаний: ±

Сделал раздельный расчет (по примеру Романа) делимость на двойку и на все остальные, стало работать быстрее чем у Романа.
Также есть решение формулами (используется множество ячеек), работает до чисел 2^40
 
Ответить
СообщениеСделал раздельный расчет (по примеру Романа) делимость на двойку и на все остальные, стало работать быстрее чем у Романа.
Также есть решение формулами (используется множество ячеек), работает до чисел 2^40

Автор - MCH
Дата добавления - 27.07.2015 в 21:16
Udik Дата: Понедельник, 27.07.2015, 22:15 | Сообщение № 9
Группа: Друзья
Ранг: Старожил
Сообщений: 1588
Репутация: 192 ±
Замечаний: 0% ±

Excel 2016 х 64
а вот и мой трактор :)

[vba]
Код

'выводит все простые числа до корня из n в табличку
Sub tblProst2(maxNum As Single)

Static k As Long
Static j As Integer
Static flP As Byte

j = 0
Worksheets("tbl").Activate
Columns(1).ClearContents
For k = 2 To Int(Sqr(maxNum))
If checkNum(k) Then
     j = j + 1
     Cells(j, 1).Value = k
End If
Next k
j = 0
End Sub

'основная функция

Public Sub disProst()
Static chNumber As Double
Static i As Long
Static j As Long
Static flEnd As Byte
Static str1 As String
Static t1 As Single
Dim arrTbl() As Long

chNumber = CDbl(Worksheets("basa").Cells(1, 1))
If (chNumber - Int(chNumber)) > 0 Then MsgBox "Err: Дробное число": Exit Sub
If chNumber < 4 Then MsgBox "Err: число меньше 4-х": Exit Sub
t1 = Timer
Application.StatusBar = "Идёт перебор вариантов..."
'AccelerateExcel

flEnd = 1
str1 = "1"

If checkNum(chNumber) Then
     str1 = str1 & "x" & "Prime"
Else
     tblProst2 (chNumber)
     i = 1
     Worksheets("tbl").Activate

     j = Columns("A").Find("*", [A1], SearchDirection:=xlPrevious, LookIn:=xlValues).Row
     ReDim arrTbl(1 To j)

     For i = 1 To j
         arrTbl(i) = Cells(i, 1)
     Next i
     Do
         For i = 1 To j
             If ModBig(chNumber, arrTbl(i)) = 0 Then
             str1 = str1 & "x" & arrTbl(i)
             chNumber = chNumber / arrTbl(i)
             If checkNum(chNumber) Then flEnd = 0: str1 = str1 & "x" & chNumber
             Exit For
             End If
         Next i
     Loop While flEnd
End If
Worksheets("basa").Activate
str1 = Mid(str1, 3)
Cells(2, 1) = str1
'disAccelerateExcel
Application.StatusBar = "Перебор вариантов закончен"
Cells(2, 2) = "Прошло: " & Int(Timer - t1) & "с"

End Sub
'
' проверяем простое число или нет
Private Function checkNum(num) As Byte
Static i As Single
Static flP As Byte
Static buff As Integer
Static k As Single

flP = 1
k = Int(Sqr(num))
For i = 2 To k
     If ModBig(num, i) = 0 Then flP = 0: Exit For
     If ModBig(i, 1000) = 0 Then buff = DoEvents 'возвращаем операционке возможность действия, чтобы не было подвисания
     ''End If
Next i
checkNum = flP
End Function

'
'замена вба мод для работы с большими числами
Function ModBig(Num1, Num2) As Double
   ModBig = Num1 - Fix(Num1 / Num2) * Num2
End Function

[/vba]
К сообщению приложен файл: prost_mnoj.xlsb (45.9 Kb)


вот вам барабан
яд 41001231307558 wm R419131876897
udik1968@gmail.com
 
Ответить
Сообщениеа вот и мой трактор :)

[vba]
Код

'выводит все простые числа до корня из n в табличку
Sub tblProst2(maxNum As Single)

Static k As Long
Static j As Integer
Static flP As Byte

j = 0
Worksheets("tbl").Activate
Columns(1).ClearContents
For k = 2 To Int(Sqr(maxNum))
If checkNum(k) Then
     j = j + 1
     Cells(j, 1).Value = k
End If
Next k
j = 0
End Sub

'основная функция

Public Sub disProst()
Static chNumber As Double
Static i As Long
Static j As Long
Static flEnd As Byte
Static str1 As String
Static t1 As Single
Dim arrTbl() As Long

chNumber = CDbl(Worksheets("basa").Cells(1, 1))
If (chNumber - Int(chNumber)) > 0 Then MsgBox "Err: Дробное число": Exit Sub
If chNumber < 4 Then MsgBox "Err: число меньше 4-х": Exit Sub
t1 = Timer
Application.StatusBar = "Идёт перебор вариантов..."
'AccelerateExcel

flEnd = 1
str1 = "1"

If checkNum(chNumber) Then
     str1 = str1 & "x" & "Prime"
Else
     tblProst2 (chNumber)
     i = 1
     Worksheets("tbl").Activate

     j = Columns("A").Find("*", [A1], SearchDirection:=xlPrevious, LookIn:=xlValues).Row
     ReDim arrTbl(1 To j)

     For i = 1 To j
         arrTbl(i) = Cells(i, 1)
     Next i
     Do
         For i = 1 To j
             If ModBig(chNumber, arrTbl(i)) = 0 Then
             str1 = str1 & "x" & arrTbl(i)
             chNumber = chNumber / arrTbl(i)
             If checkNum(chNumber) Then flEnd = 0: str1 = str1 & "x" & chNumber
             Exit For
             End If
         Next i
     Loop While flEnd
End If
Worksheets("basa").Activate
str1 = Mid(str1, 3)
Cells(2, 1) = str1
'disAccelerateExcel
Application.StatusBar = "Перебор вариантов закончен"
Cells(2, 2) = "Прошло: " & Int(Timer - t1) & "с"

End Sub
'
' проверяем простое число или нет
Private Function checkNum(num) As Byte
Static i As Single
Static flP As Byte
Static buff As Integer
Static k As Single

flP = 1
k = Int(Sqr(num))
For i = 2 To k
     If ModBig(num, i) = 0 Then flP = 0: Exit For
     If ModBig(i, 1000) = 0 Then buff = DoEvents 'возвращаем операционке возможность действия, чтобы не было подвисания
     ''End If
Next i
checkNum = flP
End Function

'
'замена вба мод для работы с большими числами
Function ModBig(Num1, Num2) As Double
   ModBig = Num1 - Fix(Num1 / Num2) * Num2
End Function

[/vba]

Автор - Udik
Дата добавления - 27.07.2015 в 22:15
_Boroda_ Дата: Понедельник, 27.07.2015, 23:01 | Сообщение № 10
Группа: Модераторы
Ранг: Местный житель
Сообщений: 16675
Репутация: 6481 ±
Замечаний: 0% ±

2003; 2007; 2010; 2013 RUS
а вот и мой трактор

Граждане трактористы, давайте смотреть правила той ветки форума, в которой постите.
Мне вот уже неинтересно стало, даже пытаться не буду, хотя мысль была.
И не нужно писать "А зачем тогда смотрел?". Да, знаю, любопытный я.


Скажи мне, кудесник, любимец ба’гов...
Платная помощь:
Boroda_Excel@mail.ru
Яндекс-деньги: 41001632713405 | Webmoney: R289877159277; Z102172301748; E177867141995
 
Ответить
Сообщение
а вот и мой трактор

Граждане трактористы, давайте смотреть правила той ветки форума, в которой постите.
Мне вот уже неинтересно стало, даже пытаться не буду, хотя мысль была.
И не нужно писать "А зачем тогда смотрел?". Да, знаю, любопытный я.

Автор - _Boroda_
Дата добавления - 27.07.2015 в 23:01
ikki Дата: Среда, 29.07.2015, 00:28 | Сообщение № 11
Группа: Друзья
Ранг: Старожил
Сообщений: 1906
Репутация: 504 ±
Замечаний: 0% ±

Excel 2003, 2010
Rioran, поиздевался немного над твоим файлом.
таки Redim Preserve - медленнее сцепления строк.
в максимуме разница доходит до почти четырехкратной.
К сообщению приложен файл: 3058617.xlsb (19.9 Kb)


помощь по Excel и VBA
ikki@fxmail.ru, icq 592842413, skype alex.ikki


Сообщение отредактировал ikki - Среда, 29.07.2015, 00:29
 
Ответить
СообщениеRioran, поиздевался немного над твоим файлом.
таки Redim Preserve - медленнее сцепления строк.
в максимуме разница доходит до почти четырехкратной.

Автор - ikki
Дата добавления - 29.07.2015 в 00:28
Rioran Дата: Среда, 29.07.2015, 09:48 | Сообщение № 12
Группа: Авторы
Ранг: Ветеран
Сообщений: 903
Репутация: 290 ±
Замечаний: 0% ±

Excel 2013
ikki, классно получилось =) Новая скорость мне больше нравится. Но мне пришлось переделать то, как ты работаешь с библиотекой "kernel32", чтобы расчёт времени заработал на моей 64-х битной системе:

[vba]
Код
#If VBA7 Then
     Public Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long '64 Bit Systems
#Else
     Public Declare Function GetTickCount Lib "kernel32" () As Long '32 Bit Systems
#End If
[/vba]


Роман, Москва, voronov_rv@mail.ru
Яндекс-Деньги: 41001312674279
 
Ответить
Сообщениеikki, классно получилось =) Новая скорость мне больше нравится. Но мне пришлось переделать то, как ты работаешь с библиотекой "kernel32", чтобы расчёт времени заработал на моей 64-х битной системе:

[vba]
Код
#If VBA7 Then
     Public Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long '64 Bit Systems
#Else
     Public Declare Function GetTickCount Lib "kernel32" () As Long '32 Bit Systems
#End If
[/vba]

Автор - Rioran
Дата добавления - 29.07.2015 в 09:48
Udik Дата: Среда, 29.07.2015, 20:07 | Сообщение № 13
Группа: Друзья
Ранг: Старожил
Сообщений: 1588
Репутация: 192 ±
Замечаний: 0% ±

Excel 2016 х 64
Переделал свой вариант, теперь первый после ресета чуть больше 3-х секунд, последующие около 0,1. Это на близких к максимальному.


вот вам барабан
яд 41001231307558 wm R419131876897
udik1968@gmail.com
 
Ответить
СообщениеПеределал свой вариант, теперь первый после ресета чуть больше 3-х секунд, последующие около 0,1. Это на близких к максимальному.

Автор - Udik
Дата добавления - 29.07.2015 в 20:07
MCH Дата: Суббота, 01.08.2015, 17:56 | Сообщение № 14
Группа: Админы
Ранг: Старожил
Сообщений: 2003
Репутация: 751 ±
Замечаний: ±

Т.к. решения уже выложены, то выкладываю собственное решение.
Сделано на формулах и через UDF, работает для чисел 2^40 (и для больших, формулы ограничены 40 множителями, но это очень легко исправить для формул ограничение именно 2^40 т.к. строк на листе всего 1048576)
К сообщению приложен файл: PrimeFact_test.xlsm (96.7 Kb)
 
Ответить
СообщениеТ.к. решения уже выложены, то выкладываю собственное решение.
Сделано на формулах и через UDF, работает для чисел 2^40 (и для больших, формулы ограничены 40 множителями, но это очень легко исправить для формул ограничение именно 2^40 т.к. строк на листе всего 1048576)

Автор - MCH
Дата добавления - 01.08.2015 в 17:56
Udik Дата: Суббота, 01.08.2015, 18:14 | Сообщение № 15
Группа: Друзья
Ранг: Старожил
Сообщений: 1588
Репутация: 192 ±
Замечаний: 0% ±

Excel 2016 х 64
Э, изначально вроде на 2^31-1 было условие, я на него ориентировался.
К сообщению приложен файл: 3993758.xlsb (22.2 Kb)


вот вам барабан
яд 41001231307558 wm R419131876897
udik1968@gmail.com
 
Ответить
СообщениеЭ, изначально вроде на 2^31-1 было условие, я на него ориентировался.

Автор - Udik
Дата добавления - 01.08.2015 в 18:14
MCH Дата: Воскресенье, 02.08.2015, 08:32 | Сообщение № 16
Группа: Админы
Ранг: Старожил
Сообщений: 2003
Репутация: 751 ±
Замечаний: ±

изначально вроде на 2^31-1 было условие

Мой код на типах Long работает немного быстрее, чем на Double, разница в коде - только в объявлении типов переменных.
Но Double позволяет разложить на множители число состоящие из пятнадцати девяток: 999999999999999 = 3*3*3*31*37*41*271*2906161
Для больших чисел происходит потеря точности связанная с типом Double.
Для Long ограничение - 2^31-1
 
Ответить
Сообщение
изначально вроде на 2^31-1 было условие

Мой код на типах Long работает немного быстрее, чем на Double, разница в коде - только в объявлении типов переменных.
Но Double позволяет разложить на множители число состоящие из пятнадцати девяток: 999999999999999 = 3*3*3*31*37*41*271*2906161
Для больших чисел происходит потеря точности связанная с типом Double.
Для Long ограничение - 2^31-1

Автор - MCH
Дата добавления - 02.08.2015 в 08:32
Udik Дата: Понедельник, 03.08.2015, 17:46 | Сообщение № 17
Группа: Друзья
Ранг: Старожил
Сообщений: 1588
Репутация: 192 ±
Замечаний: 0% ±

Excel 2016 х 64
Попробовал переделать свой код под 2^40, теперь первичная настройка занимает почти 4 мин %) , но последующие считает меньше 1 сек.
1 099 511 627 773 =13x84577817521 (Прошло: 0,6796875с)

==
Сократил первичку до 70с


вот вам барабан
яд 41001231307558 wm R419131876897
udik1968@gmail.com


Сообщение отредактировал Udik - Понедельник, 03.08.2015, 19:38
 
Ответить
СообщениеПопробовал переделать свой код под 2^40, теперь первичная настройка занимает почти 4 мин %) , но последующие считает меньше 1 сек.
1 099 511 627 773 =13x84577817521 (Прошло: 0,6796875с)

==
Сократил первичку до 70с

Автор - Udik
Дата добавления - 03.08.2015 в 17:46
miver Дата: Пятница, 14.08.2015, 14:10 | Сообщение № 18
Группа: Проверенные
Ранг: Форумчанин
Сообщений: 190
Репутация: 37 ±
Замечаний: 0% ±

Excel 2010
С учетом ограничения 2 до 2^31-1 и быстродействия
Разработал функцию, которая, в самом сложном варианте 2 147 483 647, считает мгновенно (у меня выдает максимум 4 миллисекунды)
Размер функции порядка 40 строк + дополнительные данные на скрытом листе
 
Ответить
СообщениеС учетом ограничения 2 до 2^31-1 и быстродействия
Разработал функцию, которая, в самом сложном варианте 2 147 483 647, считает мгновенно (у меня выдает максимум 4 миллисекунды)
Размер функции порядка 40 строк + дополнительные данные на скрытом листе

Автор - miver
Дата добавления - 14.08.2015 в 14:10
MCH Дата: Пятница, 14.08.2015, 21:18 | Сообщение № 19
Группа: Админы
Ранг: Старожил
Сообщений: 2003
Репутация: 751 ±
Замечаний: ±

(у меня выдает максимум 4 миллисекунды)

Размер функции порядка 40 строк + дополнительные данные на скрытом листе

код, который я опубликовал ранее, переведя на Long (вместо Double)
[vba]
Код
Function PrimeFact2$(ByVal n&)
        Dim i&, txt$
        While n Mod 2 = 0 And n > 3
            n = n \ 2
            txt = txt & "*2"
        Wend
        i = 3
        While CDbl(i) * i <= n
            If n Mod i Then i = i + 2 Else n = n \ i: txt = txt & "*" & i
        Wend
        If txt = "" Then PrimeFact2 = "Prime" Else PrimeFact2 = Mid$(txt, 2) & "*" & n
End Function
[/vba]
Всего состоит из 12 строчек, и на 1000 повторений для числа 2 147 483 647 работает менее секунды (0,6 - 0,625 сек./1000 повторений на моем компьютере, т.е. 0,6 миллисекунды на одно повторение)
 
Ответить
Сообщение
(у меня выдает максимум 4 миллисекунды)

Размер функции порядка 40 строк + дополнительные данные на скрытом листе

код, который я опубликовал ранее, переведя на Long (вместо Double)
[vba]
Код
Function PrimeFact2$(ByVal n&)
        Dim i&, txt$
        While n Mod 2 = 0 And n > 3
            n = n \ 2
            txt = txt & "*2"
        Wend
        i = 3
        While CDbl(i) * i <= n
            If n Mod i Then i = i + 2 Else n = n \ i: txt = txt & "*" & i
        Wend
        If txt = "" Then PrimeFact2 = "Prime" Else PrimeFact2 = Mid$(txt, 2) & "*" & n
End Function
[/vba]
Всего состоит из 12 строчек, и на 1000 повторений для числа 2 147 483 647 работает менее секунды (0,6 - 0,625 сек./1000 повторений на моем компьютере, т.е. 0,6 миллисекунды на одно повторение)

Автор - MCH
Дата добавления - 14.08.2015 в 21:18
miver Дата: Понедельник, 17.08.2015, 09:48 | Сообщение № 20
Группа: Проверенные
Ранг: Форумчанин
Сообщений: 190
Репутация: 37 ±
Замечаний: 0% ±

Excel 2010
Для ясности выложу свое решение ;)
К сообщению приложен файл: 9771990.xlsb (45.7 Kb)
 
Ответить
СообщениеДля ясности выложу свое решение ;)

Автор - miver
Дата добавления - 17.08.2015 в 09:48
Мир MS Excel » Работа и общение » Мозговой штурм » Разложить число на простые множители (VBA)
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!