none
arrotondamento numero decimale in intero RRS feed

  • Domanda

  • dovrei ottimizzare in tempo di calcolo questa istruzione:

    nm è un numero reale qualsiasi, può quindi essere anche negativo, per esempio:-15.001, 17.88151, ecc...
    k è il margine di errore ed è una costante uguale a 0.000000001

    in pratica mi serve ottimizzare questa istruzione in termini di tempo di calcolo
    If (((nm - Int(nm)) <= k) Or (1 - nm + Int(nm)) <= k) Then

    esempio: 35.000000001 e 34.999999999 deve restituire 35, vale la stessa cosa per i numeri negativi, è un arrotondamento di k all'intero più vicino

    martedì 7 marzo 2017 17:25

Risposte

  • ok risolto, sembra banale ma è così, visto che nessuno mi ha risposto, ecco la soluzione, e volendo forse posso anche trovare una soluzione migliore eliminando Abs... vi farò sapere. grazie lo stesso

    : test 1 = 4.699219 sec.
    : test 2 = 4.644531 sec.
    : test 3 = 3.714844 sec.
    Public Sub xTest()
     Const k As Double = 0.000000001
     Dim Tm As Single, x1 As Long, nm As Double, xMtr(1 To 99) As Boolean, xx As Long
     Tm = Timer
     For x1 = 1 To 10 ^ 8
      nm = -15 ': 36.00000001 : 35.99999999 : 101
      '1° test
      'If (((nm - Int(nm)) <= k) Or (1 - nm + Int(nm)) <= k) Then
      '2° test
      'If Abs(nm - CLng(nm)) <= k Then
      '3° test
      xx = nm
      If Abs(nm - xx) <= k Then
         '.... code ....
      End If
     Next x1
     Debug.Print Timer - Tm
    End Sub


    • Modificato makexcel mercoledì 8 marzo 2017 08:13
    • Contrassegnato come risposta makexcel mercoledì 8 marzo 2017 08:14
    mercoledì 8 marzo 2017 08:13

Tutte le risposte

  • non risponde nessuno?, ho provato con Clng ma i tempi sono gli stessi

    Public Sub xTest()
     Const k As Double = 0.000000001
     Dim Tm As Single, x1 As Long, nm As Double
     Tm = Timer
     For x1 = 1 To 10 ^ 8
      nm = -15 ': 36.00000001 : 35.99999999 : 101
      
      '1° test
      'If (((nm - Int(nm)) <= k) Or (1 - nm + Int(nm)) <= k) Then
      
      '2° test
      'If Abs(nm - CLng(nm)) <= k Then
      
         '.... code ....
    
      End If
     Next x1
     Debug.Print Timer - Tm
    End Sub



    • Modificato makexcel martedì 7 marzo 2017 19:50
    martedì 7 marzo 2017 19:48
  • ok risolto, sembra banale ma è così, visto che nessuno mi ha risposto, ecco la soluzione, e volendo forse posso anche trovare una soluzione migliore eliminando Abs... vi farò sapere. grazie lo stesso

    : test 1 = 4.699219 sec.
    : test 2 = 4.644531 sec.
    : test 3 = 3.714844 sec.
    Public Sub xTest()
     Const k As Double = 0.000000001
     Dim Tm As Single, x1 As Long, nm As Double, xMtr(1 To 99) As Boolean, xx As Long
     Tm = Timer
     For x1 = 1 To 10 ^ 8
      nm = -15 ': 36.00000001 : 35.99999999 : 101
      '1° test
      'If (((nm - Int(nm)) <= k) Or (1 - nm + Int(nm)) <= k) Then
      '2° test
      'If Abs(nm - CLng(nm)) <= k Then
      '3° test
      xx = nm
      If Abs(nm - xx) <= k Then
         '.... code ....
      End If
     Next x1
     Debug.Print Timer - Tm
    End Sub


    • Modificato makexcel mercoledì 8 marzo 2017 08:13
    • Contrassegnato come risposta makexcel mercoledì 8 marzo 2017 08:14
    mercoledì 8 marzo 2017 08:13
  • Non ti basta semplicemente un CInt ?

     Qui  puoi leggere come arrotonda


    Oppure usare Math.Round come descritto qui
    • Modificato vbMizio mercoledì 8 marzo 2017 13:16
    mercoledì 8 marzo 2017 13:14
  • ok grazie. il risultato in termini di tempo di calcolo, di CInt si avvicina molto a quello di CLng. Math.Round è quello che svolge alla perfezione tutto il ragionamento del problema, con il solo difetto che molto lento. comunque per il momento le due soluzioni migliori sono quelle di utilizzare CInt e quella di passare il valore del numero decimale ad un numero long (3° test dell'esempio).
    giovedì 9 marzo 2017 07:53
  • Mi sembra molto strano che Math.Round ti risulti meno veloce.

    Nel tuo codice "definitivo" c'è anche il costrutto If...Then? Già dover valutare diverse condizioni porta via tempo CPU.

    giovedì 9 marzo 2017 08:34
  • prova a fare tu dei test di velocità: 10^8 volte, con:
    If(Abs(nm-CLng(nm)))<=k
    If(Abs(nm-CInt(nm)))<=k
    If(Abs(nm-Math.Round(nm,9)))<=k
    If((nm-Int(nm))<=k) or ((1-nm+Int(nm))<=k)

    forse la tipologia di processore può influire sulle prestazioni di varie funzioni? non penso?

    giovedì 9 marzo 2017 15:43