PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Числа и действия


Числа и действия

Сообщений 1 страница 12 из 12

1

Планирую попрактиковаться с формулами и вычислениями в PB, но уже на начальном этапе возникла проблема с TextGadget. Мне нужно что бы в этом гаджете можно было написать, например, X в квадрате. Сам вопрос: как добавлять верхний (или нижний) индекс к тексту. Надеюсь вопрос понятен.

0

2

Возведение в степень Pow(a.f,b.f)
Че то больше не знаю в пурике.

Отредактировано haav (31.03.2010 22:58:45)

0

3

haav, а можно примерчик небольшой?

0

4

a.f=2
b.f=5
Debug Pow(a,b)

Ну или просто Debug Pow(2,3)

Отредактировано haav (31.03.2010 23:07:38)

0

5

Вот калькулятор, может пригодится

Код:
#EVAL_NUMS = "0123456789"  ;Die Zahlen von 0 bis 9 
#EVAL_GENAUGK = 65         ;Genauigkeit fьr StrF() - 65 sollte eigentlich genьgen, mehr bringt sowieso nichts 
#EVAL_DWARF = 0.00001      ;Alles was kleiner als dieser Wert ist wird wissenschaftlich notiert 
#EVAL_GIANT = 1000000      ;Alles was grцЯer-gleich ist wird wissenschaftlich notiert 

Procedure.s MyEval(expr.s) ; wird nur intern von Funktion Eval() aufgerufen 
  Protected exprLeft.s, exprRight.s, exprMid.s, Result.s, exprLen.l, valLeft.f, valRight.f, i.l 
  ;Debug "in: " + expr 
  EVAL_START: 
  exprLen = Len(expr) 
  For i = 1 To exprLen ; In dieser Schleife schauen wir nach der ersten цffnenden Klammer 
    exprMid = Mid(expr, i, 1) 
    If exprMid = "(" 
      BracketCount = 1 
      start = i 
      For i = i+1 To exprLen ; wurde eine цffnende Klammer gefunden sucht diese Schleife die dazu passende schlieЯende 
        exprMid = Mid(expr, i, 1) 
        If exprMid = "(" ;Sch... , noch eine Klammerebene 
          BracketCount + 1 
        ElseIf exprMid = ")" 
          BracketCount - 1 
          If BracketCount = 0 ; gefunden 
            exprLeft = Left(expr, start-1) 
            exprRight = Right(expr, exprLen - i) 
            exprMid = Mid(expr, start+1, exprLen - Len(exprLeft + exprRight) - 2) 
            exprMid = MyEval(exprMid) ; berechnen des mittleren Abschnitts (der in der Klammer) 
            If exprMid="x" 
              ProcedureReturn "x" 
            EndIf 
            expr = exprLeft + exprMid + exprRight 
            Goto EVAL_START   ;des Goto musste mal sein, ich brauch's ja sonst nie 
          EndIf 
        EndIf 
      Next 
    EndIf 
  Next 
  
  For i = exprLen To 1 Step -1 
    exprMid = Mid(expr, i, 1) 
    Select exprMid 
      Case "=" 
        ;Debug "ok" 
        exprLeft  = MyEval(Left(expr, i-1)) 
        exprRight = MyEval(Right(expr, exprLen - i)) 
        If exprLeft="x" Or exprRight="x" 
          ProcedureReturn "x" 
        EndIf 
        If exprLeft = exprRight 
          ProcedureReturn "1" 
        Else 
          ProcedureReturn "0.0" 
        EndIf 
      Case "<" 
        ;Debug "ok" 
        exprLeft  = MyEval(Left(expr, i-1)) 
        exprRight = MyEval(Right(expr, exprLen - i)) 
        If exprLeft="x" Or exprRight="x" 
          ProcedureReturn "x" 
        EndIf 
        If ValF(exprLeft) < ValF(exprRight) 
          ProcedureReturn "1" 
        Else 
          ProcedureReturn "0.0" 
        EndIf 
      Case ">" 
        ;Debug "ok" 
        exprLeft  = MyEval(Left(expr, i-1)) 
        exprRight = MyEval(Right(expr, exprLen - i)) 
        If exprLeft="x" Or exprRight="x" 
          ProcedureReturn "x" 
        EndIf 
        If ValF(exprLeft) > ValF(exprRight) 
          ProcedureReturn "1" 
        Else 
          ProcedureReturn "0.0" 
        EndIf 
    EndSelect 
  Next 
  
  
  For i = exprLen To 1 Step -1 
    exprMid = Mid(expr, i, 1) 
    Select exprMid 
      Case "&" 
        exprLeft  = MyEval(Left(expr, i-1)) 
        exprRight = MyEval(Right(expr, exprLen - i)) 
        If exprLeft="x" Or exprRight="x" 
          ProcedureReturn "x" 
        EndIf 
        intL.l = Val(exprLeft) 
        intR.l = Val(exprRight) 
        intR = intR & intL 
        Result = StrF(intR, #EVAL_GENAUGK) 
        ProcedureReturn Result 
      Case "|" 
        exprLeft  = MyEval(Left(expr, i-1)) 
        exprRight = MyEval(Right(expr, exprLen - i)) 
        If exprLeft="x" Or exprRight="x" 
          ProcedureReturn "x" 
        EndIf 
        intL.l = Val(exprLeft) 
        intR.l = Val(exprRight) 
        intR = intR | intL 
        Result = StrF(intR, #EVAL_GENAUGK) 
        ProcedureReturn Result 
    EndSelect 
  Next 
  
  For i = exprLen To 1 Step -1 ; + und - Terme ausrechnen 
    exprMid = Mid(expr, i, 1) 
    Select exprMid 
      Case "+" 
        exprLeft  = Left(expr, i-1) 
        ; statt Addition kцnnte es auch einfach nur ein Vorzeichen sein. Das wollen wir natьrlich nicht berechnen. 
        If exprLeft<>"" And FindString(#EVAL_NUMS ,Right(exprLeft, 1), 1) 
          exprLeft = MyEval(exprLeft) 
          exprRight = MyEval(Right(expr, exprLen - i)) 
          If exprLeft="x" Or exprRight="x" 
            ProcedureReturn "x" 
          EndIf 
          Result = StrF(ValF(exprLeft) + ValF(exprRight), #EVAL_GENAUGK) 
          ProcedureReturn Result 
        EndIf 
      Case "-" 
        exprLeft  = Left(expr, i-1) 
        ; ditto fьr Subtraktion 
        If exprLeft<>"" And FindString(#EVAL_NUMS ,Right(exprLeft, 1), 1) 
          exprLeft = MyEval(exprLeft) 
          exprRight = MyEval(Right(expr, exprLen - i)) 
          If exprLeft="x" Or exprRight="x" 
            ProcedureReturn "x" 
          EndIf 
          Result = StrF(ValF(exprLeft) - ValF(exprRight), #EVAL_GENAUGK) 
          ProcedureReturn Result 
        EndIf 
    EndSelect 
  Next 
  For i = exprLen To 1 Step -1 ; Malnehmen, Teilen und Modulo (Restwertbildung) 
    exprMid = Mid(expr, i, 1) 
    Select exprMid 
      Case "*" 
        exprLeft  = MyEval(Left(expr, i-1)) 
        exprRight = MyEval(Right(expr, exprLen - i)) 
        If exprLeft="x" Or exprRight="x" 
          ProcedureReturn "x" 
        EndIf 
        Result = StrF(ValF(exprLeft) * ValF(exprRight), #EVAL_GENAUGK) 
        ProcedureReturn Result 
      Case "/" 
        exprLeft  = MyEval(Left(expr, i-1)) 
        exprRight = MyEval(Right(expr, exprLen - i)) 
        If exprLeft="x" Or exprRight="x" 
          ProcedureReturn "x" 
        EndIf 
        Result = StrF(ValF(exprLeft) / ValF(exprRight), #EVAL_GENAUGK) 
        ProcedureReturn Result 
      Case "%" 
        exprLeft  = MyEval(Left(expr, i-1)) 
        exprRight = MyEval(Right(expr, exprLen - i)) 
        If exprLeft="x" Or exprRight="x" 
          ProcedureReturn "x" 
        EndIf 
        valLeft = ValF(exprLeft) 
        valRight = ValF(exprRight) 
        Result = StrF(valLeft-Int(valLeft/valRight)*valRight, #EVAL_GENAUGK) 
        ProcedureReturn Result 
    EndSelect 
  Next 
  
  For i = exprLen To 1 Step -1 ; Potentes Ding 
    exprMid = Mid(expr, i, 1) 
    If exprMid = "^" 
      exprLeft  = MyEval(Left(expr, i-1)) 
      exprRight = MyEval(Right(expr, exprLen - i)) 
      If exprLeft="x" Or exprRight="x" 
        ProcedureReturn "x" 
      EndIf 
      valLeft = ValF(exprLeft) 
      valRight = ValF(exprRight) 
      Result = StrF(Pow(valLeft, valRight), #EVAL_GENAUGK) 
      ProcedureReturn Result 
    EndIf 
  Next 
  
  exprLeft = Left(expr, 1) 
  If exprLeft = "+" Or exprLeft = "-" 
    vz.s = exprLeft 
    expr = Right(expr, exprLen-1) 
    exprLen = Len(expr) 
  Else 
    vz = "" 
  EndIf 
  
  ;und nun bis zum Schluss noch einige nьtzliche Funktionen 
  exprLeft = Left(expr, 4) 
  Select exprLeft 
    Case "ASIN" 
      exprRight = Right(expr, exprLen - 4) 
      valRight = ValF(exprRight) 
      Result = StrF(ASin(valRight), #EVAL_GENAUGK) 
      ProcedureReturn vz + Result 
    Case "ACOS" 
      exprRight = Right(expr, exprLen - 4) 
      valRight = ValF(exprRight) 
      Result = StrF(ACos(valRight), #EVAL_GENAUGK) 
      ProcedureReturn vz + Result 
    Case "ATAN" 
      exprRight = Right(expr, exprLen - 4) 
      valRight = ValF(exprRight) 
      Result = StrF(ATan(valRight), #EVAL_GENAUGK) 
      ProcedureReturn vz + Result 
  EndSelect 
  
  exprLeft = Left(expr, 3) 
  Select exprLeft 
    ;  Select Left(expr, 3) ; Merkwьrdiger Bug wenn es direkt so aufgerufen wird !!!!!!!!!!!!!!!!!!!!!! 
    Case "SQR" 
      exprRight = Right(expr, exprLen - 3) 
      valRight = ValF(exprRight) 
      If valRight <0 
        ProcedureReturn "x" 
      EndIf 
      Result = StrF(Sqr(valRight), #EVAL_GENAUGK) 
      ProcedureReturn vz + Result 
    Case "LOG" 
      exprRight = Right(expr, exprLen - 3) 
      valRight = ValF(exprRight) 
      If valRight <0 
        ProcedureReturn "x" 
      EndIf 
      Result = StrF(Log10(valRight), #EVAL_GENAUGK) 
      ProcedureReturn vz + Result 
    Case "SIN" 
      exprRight = Right(expr, exprLen - 3) 
      valRight = ValF(exprRight) 
      Result = StrF(Sin(valRight), #EVAL_GENAUGK) 
      ProcedureReturn vz + Result 
    Case "COS" 
      exprRight = Right(expr, exprLen - 3) 
      valRight = ValF(exprRight) 
      Result = StrF(Cos(valRight), #EVAL_GENAUGK) 
      ProcedureReturn vz + Result 
    Case "TAN" 
      exprRight = Right(expr, exprLen - 3) 
      valRight = ValF(exprRight) 
      Result = StrF(Tan(valRight), #EVAL_GENAUGK) 
      ProcedureReturn vz + Result 
    Case "ABS" 
      exprRight = Right(expr, exprLen - 3) 
      valRight = ValF(exprRight) 
      Result = StrF(Abs(valRight), #EVAL_GENAUGK) 
      ProcedureReturn vz + Result 
    Case "INV" 
      exprRight = Right(expr, exprLen - 3) 
      valRight = ValF(exprRight) 
      If valRight =0 
        ProcedureReturn "x" 
      EndIf 
      Result = StrF(1/valRight, #EVAL_GENAUGK) 
      ProcedureReturn vz + Result 
  EndSelect 
  
  exprLeft = Left(expr, 2) 
  Select exprLeft 
    Case "LN" 
      exprRight = Right(expr, exprLen - 2) 
      valRight = ValF(exprRight) 
      If valRight <0 
        ProcedureReturn "x" 
      EndIf 
      Result = StrF(Log(valRight), #EVAL_GENAUGK) 
      ProcedureReturn vz + Result 
  EndSelect 
  
  exprLeft = Left(expr, 1) 
  Select exprLeft 
    Case "!" 
      exprRight = Right(expr, exprLen - 1) 
      valRight = ValF(exprRight) 
      If Int(valRight)>=0 
        valLeft = 1 
        For i = 2 To Int(valRight) 
          valLeft * i 
          ;Debug valLeft 
        Next 
      Else 
        ProcedureReturn "x" 
      EndIf 
      Result = StrF(valLeft, #EVAL_GENAUGK) 
      ProcedureReturn vz + Result 
  EndSelect 
  
  ProcedureReturn vz + StrF(ValF(expr), #EVAL_GENAUGK) 
EndProcedure 

Procedure.s Calculate(Gadget) ; Калькулятор
  Shared Eval_LastResult.s 
  Shared Eval_Memory.s, Eval_Memory1.s, Eval_Memory2.s, Eval_Memory3.s, Eval_Memory4.s, Eval_Memory5.s, Eval_Memory6.s, Eval_Memory7.s, Eval_Memory8.s, Eval_Memory9.s 
  
  If IsGadget(Gadget)=0
    ProcedureReturn ""
  EndIf
  
  expr.s=GetGadgetText(Gadget)
  expr = UCase(expr) ; Alles GroЯbuchstaben, so haben wir's beim Parsen einfacher 
  expr = ReplaceString(expr, " ", "") ; Leerzeichen entfernen 
  If Left(expr, 1) = ":" 
    Select expr 
      Case ":MEM" 
        Eval_Memory = Eval_LastResult 
        expr = Eval_Memory 
        prependix.s = "M+ " 
      Case ":MEM1" 
        Eval_Memory1 = Eval_LastResult 
        expr = Eval_Memory1 
        prependix = "M1+" 
      Case ":MEM2" 
        Eval_Memory2 = Eval_LastResult 
        expr = Eval_Memory2 
        prependix = "M2+" 
      Case ":MEM3" 
        Eval_Memory3 = Eval_LastResult 
        expr = Eval_Memory3 
        prependix = "M3+" 
      Case ":MEM4" 
        Eval_Memory4 = Eval_LastResult 
        expr = Eval_Memory4 
        prependix = "M4+" 
      Case ":MEM5" 
        Eval_Memory5 = Eval_LastResult 
        expr = Eval_Memory5 
        prependix = "M5+" 
      Case ":MEM6" 
        Eval_Memory6 = Eval_LastResult 
        expr = Eval_Memory6 
        prependix = "M6+" 
      Case ":MEM7" 
        Eval_Memory7 = Eval_LastResult 
        expr = Eval_Memory7 
        prependix = "M7+" 
      Case ":MEM8" 
        Eval_Memory8 = Eval_LastResult 
        expr = Eval_Memory8 
        prependix = "M8+" 
      Case ":MEM9" 
        Eval_Memory9 = Eval_LastResult 
        expr = Eval_Memory9 
        prependix = "M9+" 
    EndSelect 
  EndIf 
  
  ; Mathematische Konstanten ersetzen 
  expr = ReplaceString(expr, "PI", "3.1415926535897932384626433832795") ; Kreiskonstante PI 
  expr = ReplaceString(expr, "EUL", "2.7182818284590452353602874713527") ; Eulersche Zahl 
  
  ; Ergebnisspeicher 
  expr = ReplaceString(expr, "MEM1", Eval_Memory1) 
  expr = ReplaceString(expr, "MEM2", Eval_Memory2) 
  expr = ReplaceString(expr, "MEM3", Eval_Memory3) 
  expr = ReplaceString(expr, "MEM4", Eval_Memory4) 
  expr = ReplaceString(expr, "MEM5", Eval_Memory5) 
  expr = ReplaceString(expr, "MEM6", Eval_Memory6) 
  expr = ReplaceString(expr, "MEM7", Eval_Memory7) 
  expr = ReplaceString(expr, "MEM8", Eval_Memory8) 
  expr = ReplaceString(expr, "MEM9", Eval_Memory9) 
  expr = ReplaceString(expr, "MEM", Eval_Memory) 
  
  expr = ReplaceString(expr, "LR", Eval_LastResult) ; Das letzte Ergebnis 
  
  expr = ReplaceString(expr, ",", ".") ; Dezimalpunkt statt Komma 
  expr = ReplaceString(expr, ":", "/") ; Beide Notationen fьr Teilen zulassen 
  
  ; Wissenschaftliche Zahlennotation zulassen 
  Repeat 
    posE = FindString(expr, "E", 1) 
    If posE > 0 And FindString("+-", Mid(expr, posE+1, 1), 1) 
      posMant = posE - 1 
      While posMant>0 And FindString(#EVAL_NUMS+".", Mid(expr, posMant, 1), 1) 
        posMant - 1 
      Wend 
      posExp = posE + 2 
      While posExp <= Len(expr) And FindString(#EVAL_NUMS+".", Mid(expr, posExp, 1), 1) 
        posExp + 1 
      Wend 
      prt1.s = Left(expr, posMant) 
      prt2.s = Mid(expr,posMant+1, posE - posMant -1) 
      prt3.s = Mid(expr, posE + 1, posExp - posE -1) 
      prt4.s = Right(expr, Len(expr)-posExp+1) 
      expr = prt1 + "(" + prt2 + "e" + prt3 + ")" + prt4 
    EndIf 
  Until posE = 0 
  expr = ReplaceString(expr, "e+", "*10^") 
  expr = ReplaceString(expr, "e-", "*10^-") 
  
  expr = MyEval(expr.s) ; Jetzt lassen wir richtig rechnen 
  If expr = "x" 
    expr = "ERROR" 
  Else 
    Eval_LastResult = expr ; und speichern das Ergebniss zur spдteren Verwendung 
    ;Debug expr 
    ; Ьberschьssige Nullen (und evtl. auch Dezimalpunkt) am Ende entfernen 
    exprLen = Len(expr) 
    While Mid(expr, exprLen, 1) = "0" 
      exprLen - 1 
    Wend 
    expr = Left(expr, exprLen) 
    If Right(expr, 1) = "." 
      expr = Left(expr, exprLen-1) 
    EndIf 
    If expr = "" 
      expr = "0" 
    EndIf 
    
    ; Bei kleinen und groЯen Zahlen die Wissenschaftliche Notation verwenden 
    If expr <> "0" And Abs(ValF(expr)) < #EVAL_DWARF 
      ;  If Abs(ValF(expr)) < #EVAL_DWARF And expr <> "0" ; auch hier ein Bug durch leicht anderen Aufruf !!!!!!!!!!!!!! 
      exprLen = Len(expr) 
      If Left(expr, 1) = "-" 
        vz.s = "-" 
        expr = Right(expr, exprLen - 3) 
      Else 
        vz = "" 
        expr = Right(expr, exprLen - 2) 
      EndIf 
      exp = 1 
      While Left(expr, 1) = "0" 
        expr = Right(expr, Len(expr)-1) 
        exp + 1 
      Wend 
      expr = vz + Left(expr, 1) + "." + Right(expr, Len(expr)-1) + "E-" + Str(exp) 
    EndIf 
    If Abs(ValF(expr)) >= #EVAL_GIANT 
      exprLen = Len(expr) 
      If Left(expr, 1) = "-" 
        vz.s = "-" 
        expr = Right(expr, exprLen - 1) 
      Else 
        vz = "" 
      EndIf 
      expr = vz + Left(expr, 1) + "." + Right(expr, Len(expr)-1) + "E+" + Str(Len(expr)-1) 
    EndIf 
    expr = prependix + expr 
    prependix = "" 
  EndIf 
  ProcedureReturn expr 
EndProcedure 



OpenWindow(0,0,0,300,100,"Калькулятор",#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
StringGadget(0,10,4,190,20,"4+4/2")
ButtonGadget(1,210,4,80,20,"Рассчитать")
StringGadget(2,10,50,190,20,"",#PB_String_ReadOnly)
Repeat
   Event=WaitWindowEvent()
   If Event=#PB_Event_Gadget
     If EventGadget()=1
       Result.s=Calculate(0)
       SetGadgetText(2,Result)
     EndIf
   EndIf
Until Event=#PB_Event_CloseWindow

0

6

Пётр, haav спасибо вам за примеры, как раз то что нужно, но я имел чуть чуть другое: мне нужно в текстовом поле вывести текст, например как в ворде, с верхним и нижнем индексом. Думаю по скрину вы все поймете: http://i057.radikal.ru/1004/9f/c7b920fd26ef.gif

0

7

Надо что-то типа этого?

http://i062.radikal.ru/1004/e2/6a59da32e72c.png

Чтобы получить такой результат, надо этот код компилировать в формате юникода.

Код:
LoadFont(0,"Arial",16)
OpenWindow(0,0,0,100,50,"",#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
TextGadget(1,20,20,50,50,"X"+Chr($b9))
SetGadgetFont(1,FontID(0))
Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow

0

8

Петр, у меня при запуски выше написанного кода получается вот что: http://s52.radikal.ru/i135/1004/02/8d32f8b9a835.gif

0

9

Так я же написал что нужно создавать прогу в формате юникода.

0

10

Пардон, невнимателен. А можешь пояснить, что значит

Код:
+Chr($b9)

? И как писать таким образом другие символы?

0

11

daiomik написал(а):

И как писать таким образом другие символы

Открываешь "Пуск" --> "Программы" --> "Стандартные" --> "Служебные" --> "Таблица символов"

0

12

Спасибо, Петр, разобрался. Кому интересно, нужно просто заменить с этого кода b9

Код:
+Chr($b9)

на другой интересующий символ, например:

Код:
LoadFont(0,"Arial",16)
OpenWindow(0,0,0,100,50,"",#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
TextGadget(1,20,20,50,50,"X"+Chr($AA))
SetGadgetFont(1,FontID(0))
Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Числа и действия