Gestione frazionin in Calcolatrice

This commit is contained in:
NicolaP
2023-01-16 17:52:08 +01:00
parent 6b4ce8bfbb
commit 0b2b071ff9
5 changed files with 180 additions and 9 deletions
+26 -3
View File
@@ -316,16 +316,39 @@ Public Class EgtCalculator
Private Sub Evaluate()
m_sBeforeEvaluate = ValueTxBx.Text
Dim bOk As Boolean = EgtUILib.EgtLuaEvalNumExpr(ValueTxBx.Text, m_DoubleResult)
Dim bOk As Boolean = False
' se impostato per dati in frazioni
Dim sDecimal As String = String.Empty
If StringFractionToStringDecimal(ValueTxBx.Text, sDecimal) Then
bOk = EgtUILib.EgtLuaEvalNumExpr(sDecimal, m_DoubleResult)
Else
bOk = EgtUILib.EgtLuaEvalNumExpr(ValueTxBx.Text, m_DoubleResult)
End If
If bOk Then
ValueTxBx.Text = DoubleToString(m_DoubleResult, 6)
m_sBeforeEvaluate = String.Empty
If nCurrFractionPattern <> FractionPattern.None And Not EgtUiUnitsAreMM() Then
ValueTxBx.Text = DoubleToStringFraction(m_DoubleResult, dPrecision)
Else
ValueTxBx.Text = DoubleToString(m_DoubleResult, 6)
m_sBeforeEvaluate = String.Empty
End If
Else
m_bErrorState = True
ValueTxBx.Foreground = Brushes.Red
ValueTxBx.TextAlignment = TextAlignment.Left
ValueTxBx.Text = m_sErrorString
End If
'Dim bOk As Boolean = EgtUILib.EgtLuaEvalNumExpr(ValueTxBx.Text, m_DoubleResult)
'If bOk Then
' ValueTxBx.Text = DoubleToString(m_DoubleResult, 6)
' m_sBeforeEvaluate = String.Empty
'Else
' m_bErrorState = True
' ValueTxBx.Foreground = Brushes.Red
' ValueTxBx.TextAlignment = TextAlignment.Left
' ValueTxBx.Text = m_sErrorString
'End If
ValueTxBx.Focus()
ValueTxBx.CaretIndex = ValueTxBx.Text.Length
End Sub
+3 -2
View File
@@ -50,7 +50,8 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="EgtUILib, Version=2.4.5.3, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\EgtUILib.2.4.5.3\lib\EgtUILib.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\EgtProg\Dll32\EgtUILib.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@@ -103,6 +104,7 @@
<Compile Include="EgtTextBox.xaml.vb">
<DependentUpon>EgtTextBox.xaml</DependentUpon>
</Compile>
<Compile Include="FractionStringConverter.vb" />
<Compile Include="InitializeEgtWPFLib.vb" />
<Compile Include="My Project\AssemblyInfo.vb">
<SubType>Code</SubType>
@@ -128,7 +130,6 @@
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
</None>
<AppDesigner Include="My Project\" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Page Include="EgtCalculator.xaml">
+146
View File
@@ -0,0 +1,146 @@
Imports System.Globalization
Imports System.Text.RegularExpressions
Imports EgtUILib
Public Module FractionStringConverter
Public Enum FractionPattern
None
Feet_Inches
Inches
End Enum
' seleziona il tipo di Pattern con cui stamoare i dati
Friend nCurrFractionPattern As FractionPattern = FractionPattern.Feet_Inches
Public Sub SetCurrFractionPattern(nCurrFraction As FractionPattern)
nCurrFractionPattern = nCurrFraction
End Sub
Friend dPrecision As Double = 64
Public Sub SetPrecision(dVal As FractionPattern)
dPrecision = dVal
End Sub
Public Function DoubleToStringFraction(dVal As Double, dBase As Double) As String
Dim sSign As String = String.Empty
If dVal < 0 Then
sSign = "-"
dVal = Math.Abs(dVal)
End If
Dim sFraction As String = String.Empty
' integer and decima part of the value
Dim dInteger As Double = Math.Floor(dVal)
Dim dFraction As Double = dVal - dInteger
' the nearest decimal numerator
Dim dNumeretor As Double = dFraction * dBase
Dim dRound As Double = Math.Round(dNumeretor)
' estimates the irreducible fraction
If dRound = 0 Then
' no decimal part
ElseIf dRound = dBase Then
' no decimal part
dInteger = dInteger + 1
Else
' simplify fraction
While dRound Mod 2 = 0
dRound = dRound / 2
dBase = dBase / 2
End While
sFraction = DoubleToString(dRound, 0) & "/" & DoubleToString(dBase, 0)
End If
' sVal: dFeet'dInteger"sFraction --- dInteger sFraction
Return WriteFraction(dInteger, sFraction)
End Function
' trasforma il valore da pollici a piedi
Private Sub ConvertInchesToFeet(ByRef dFeet As Double, ByRef dInches As Double)
If dInches = 0 Then Return
While dInches - 12 >= 0
dFeet = dFeet + 1
dInches = dInches - 12
End While
End Sub
' stampa dati in funzione del pattern dichiarato
Private Function WriteFraction(ByVal dInches As Double, sFraction As String) As String
Dim sVal As String = String.Empty
Select Case nCurrFractionPattern
Case FractionPattern.Feet_Inches
Dim dFeet As Double = 0
ConvertInchesToFeet(dFeet, dInches)
If dFeet > 0 Then
sVal = String.Format("{0}'{1}""{2}", DoubleToString(dFeet, 0), DoubleToString(dInches, 0), sFraction).Trim
Else
sVal = String.Format("{0}""{1}", DoubleToString(dInches, 0), sFraction).Trim
End If
Case FractionPattern.Inches
sVal = DoubleToString(dInches, 0) & " " & sFraction
sVal = String.Format("{0}""{1}", DoubleToString(dInches, 0), sFraction).Trim
End Select
Return sVal
End Function
' riceve la stringa sorgente e restituisce la nuova strunga in formato decimale (senza eseguire conversioni di unità)
Public Function StringFractionToStringDecimal(sVal As String, ByRef sValConverted As String) As Boolean
Dim dVal As Double = 0
' dato in ingresso: sVal = 2'3"23/32
Dim sFeet As String = String.Empty
Dim sFeetPattern As String = "^.*?(?=')"
Dim dFeet As Double = 0
Dim bOkFeet As Boolean = True
Dim bFeetExists As Boolean = False
Dim sInch As String = String.Empty
Dim sInchPattern As String = "(?<=')(.*?)(?="")" ' se la stringa contiene l'apice singolo
Dim sInchPattern1 As String = "(.*?)(?="")" ' se la stringa NON contiene l'apice singolo
Dim dInch As Double = 0
Dim bOkInch As Boolean = True
Dim bInchExists As Boolean = False
Dim sFraction As String = String.Empty
Dim sFractionPattern As String = "(?<="")(.*)" ' se la stringa contiene l'apice doppio
Dim sFractionPattern1 As String = "(?<=')(.*)" ' se la stringa NON contiene l'apice doppio ma solo quello singolo
Dim dFraction As Double = 0
Dim bOkFraction As Boolean = True
Dim bFractionExists As Boolean = False
' recupero il valore di Feet (2')
Dim sMyMatch As String = Regex.Match(sVal, sFeetPattern).Groups(1).Value
If Not String.IsNullOrEmpty(sMyMatch) Or Not String.IsNullOrWhiteSpace(sMyMatch) Then
sFeet = sMyMatch.Trim
bOkFeet = StringToDouble(sFeet, dFeet)
bFeetExists = True
End If
' recupero il valore di Inch (3") dopo i Feet - oppure direttamente i pollici
If bFeetExists Then
sMyMatch = Regex.Match(sVal, sInchPattern).Groups(1).Value
Else
sMyMatch = Regex.Match(sVal, sInchPattern1).Groups(1).Value
End If
If Not String.IsNullOrEmpty(sMyMatch) Or Not String.IsNullOrWhiteSpace(sMyMatch) Then
sInch = sMyMatch.Trim
bOkInch = StringToDouble(sInch, dInch)
bInchExists = True
End If
' recupero il valore frazionario (23/32) dopo i pollici - oppure dopo i feet - oppure direttamente i valore inteso come pollici
If bInchExists Then
sMyMatch = Regex.Match(sVal, sFractionPattern).Groups(1).Value
ElseIf bFeetExists And Not bInchExists Then
sMyMatch = Regex.Match(sVal, sFractionPattern1).Groups(1).Value
ElseIf Not bFeetExists And Not bInchExists Then
sMyMatch = sVal
End If
If Not String.IsNullOrEmpty(sMyMatch) Or Not String.IsNullOrWhiteSpace(sMyMatch) Then
sFraction = sMyMatch
bOkFraction = StringToDouble(sFraction, dFraction)
End If
' calcolo il valore decimale dell'espressione
If bOkFeet And bOkInch And bOkFraction Then
dVal = dFeet / 12 + dInch + dFraction
sValConverted = DoubleToString(dVal, 4)
Return True
Else
Return False
End If
End Function
End Module
+5
View File
@@ -1,5 +1,6 @@
Imports System.Globalization
Imports System.Runtime.InteropServices
Imports EgtUILib
Public Module Utility
@@ -37,6 +38,10 @@ Public Module Utility
Return sVal
End If
End Function
Friend Function StringToDouble(sVal As String, ByRef dVal As Double) As Boolean
If String.IsNullOrEmpty(sVal) Then Return False
Return EgtLuaEvalNumExpr(sVal, dVal)
End Function
Private m_MainWindow As Window
Public Property MainWindow As Window
-4
View File
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EgtUILib" version="2.4.5.3" targetFramework="net40-client" />
</packages>