Visualizzazione dei risultati da 1 a 7 su 7

Discussione: [C++] Unità di misura

  1. #1
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177

    [C++] Unità di misura

    Problema: gestire la possibilità di cambiare le unità di misura durante l'esecuzione di un programma. Ad esempio, se io preferisco inserire le dimensioni in cm, posso scegliere cm, un altro utente preferisce i mm, può inserire le dimensioni in mm. Stessa cosa per i risultati delle elaborazioni, sia visualizzazione a video che salvataggio dati.

    Pensavo di risolvere così: tutte le operazioni all'interno del programma vengono fatte come se i dati fossero secondo le unità di misura del sistema internazionale (m per lunghezze, kg per la massa, s per il tempo, ecc).
    La possibilità di cambiare le unità di misura viene gestita mediante una classe che serve a "manipolare" un oggetto che permette all'utente di scegliere le unità di misura.
    Questo oggetto viene passato come parametro a tutte le funzioni del programma che si occupano di input e output, in modo che verificata l'unità di misura impostata dall'utente, attraverso l'opportuno coefficiente effettuino la conversione dall'unità scelta dall'utente a quella del sistema internazionale per svolgere le operazioni su di essi, in fase di visualizzazione per passare dal sistema internazionale alle unità scelte dall'utente.

    Soluzioni migliori?

    Grazie

  2. #2
    Di norma questa è la soluzione che si usa, talvolta usando come unità interna il sottomultiplo più piccolo utilizzabile (in modo da poter lavorare con interi, se la cosa può essere utile dal punto di vista delle prestazioni o per evitare problemi di precisione FP). Spesso comunque l'oggetto che rappresenta la scelta dell'utente in termini di unità di misura viene tenuto come globale, in modo da evitare di doverlo continuamente passare in giro; in quest'ultimo caso però bisogna stare molto attenti a distinguere tra funzioni di parsing/output da/per utente e da/per formati human-readable (ma che comunque non devono essere influenzati dalle preferenze).
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Quote Originariamente inviata da MItaly Visualizza il messaggio
    Spesso comunque l'oggetto che rappresenta la scelta dell'utente in termini di unità di misura viene tenuto come globale, in modo da evitare di doverlo continuamente passare in giro; in quest'ultimo caso però bisogna stare molto attenti a distinguere tra funzioni di parsing/output da/per utente e da/per formati human-readable (ma che comunque non devono essere influenzati dalle preferenze).
    Scusa l'ignoranza, in termini terra terra?

    Vuol dire dichiarare l'oggetto "unità di misura" prima del main?

    Faccio un esempio di quello che invece pensavo di fare io.
    Nel file preferenze.h definisco

    codice:
    class unitamisura
    {
    ...//quanto serve a farlo funzionare
    }
    e in preferenze.cpp l'implementazione effettiva

    creo il programma

    codice:
    #include <iostream>
    #include <string>
    #include <windows.h>
    #include .....
    #include <preferenze.h>
    
    int main()
    {
    unitamisura umisura;
    ......
    //da qualche parte ho definito la funzione "input" dell'oggetto "oggetto"
    ......
    oggetto.input(umisura,/*altri eventuali parametri*/);
    .......
    }
    Qualche link a documentazione che parli di queste problematiche? Da quanto cercato in giro non ho trovato niente, forse perchè in prima battuta ho ristretto la ricerca alle sole pagine in italiano...

    Grazie per la disponibilità

  4. #4
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Quote Originariamente inviata da MItaly Visualizza il messaggio
    Spesso comunque l'oggetto che rappresenta la scelta dell'utente in termini di unità di misura viene tenuto come globale, in modo da evitare di doverlo continuamente passare in giro; in quest'ultimo caso però bisogna stare molto attenti a distinguere tra funzioni di parsing/output da/per utente e da/per formati human-readable (ma che comunque non devono essere influenzati dalle preferenze).
    Per la prima parte della risposta credo di essermi chiarito le idee, anche in merito a vantaggi e svantaggi legati alle dichiarazioni "globali", mi resta arabo la seconda parte

    Quote Originariamente inviata da MItaly Visualizza il messaggio
    in quest'ultimo caso però bisogna stare molto attenti a distinguere tra funzioni di parsing/output da/per utente e da/per formati human-readable (ma che comunque non devono essere influenzati dalle preferenze).
    Probabilmente fa parte dell'ABC del programmatore, ma programmando per necessità e non per professione...

    Grazie di nuovo

  5. #5
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,590
    Premesso che tutte le operazioni di input/output sono influenzate da un oggetto globale,
    Se voglio esportare il tutto in un formato standard dovrò stare attento a com'è impostato questo oggetto globale/dovrò evitare di utilizzarlo.
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

  6. #6
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Quote Originariamente inviata da Scara95 Visualizza il messaggio
    Premesso che tutte le operazioni di input/output sono influenzate da un oggetto globale,
    Se voglio esportare il tutto in un formato standard dovrò stare attento a com'è impostato questo oggetto globale/dovrò evitare di utilizzarlo.
    ...........

    (l'ignoranza è una brutta bestia)

  7. #7
    Il discorso è molto semplice: se hai delle funzioni per leggere e scrivere in "formato utente" (senza possibilità di override) devi usarle solo per la GUI, e stare attento a non usarle per compiti apparentemente simili ma che non devono essere influenzati dalle preferenze, come ad esempio la scrittura/lettura da formati file testuali.

    Mi spiego meglio con un esempio: nella libreria C esiste il concetto di "locale". Il "locale" ha come idea il contenere le impostazioni di formattazione di numeri, date, valuta, ... preferite per l'utente. In Italia, ad esempio, vogliamo i numeri con la virgola come separatore decimale, il punto (o l'apostrofo) come eventuale separatore delle migliaia, il simbolo € e due decimali per la valuta, le date in formato GG/MM/AAAA, l'ora in formato 24h, eccetera; in America invece si usa il punto come separatore decimale, la virgola per le migliaia, $ e due decimali per la valuta, le date in formato MM/GG/AAAA, l'ora in formato AM/PM.
    Ora, le funzioni di input, di output e di parsing di default (scanf, printf, strtod, ...) sono sensibili al locale: se viene impostato il locale italiano, una printf("%g\n", 1234.5) stamperà "1234,5" (o 1.234,5, dipende da un po' di cose); alla stessa maniera, scanf("%g", &var) e strtod riconosceranno il formato italiano e non più quello di default (il "locale C").

    Tutto questo andrebbe bene se le funzioni in questione fossero usate solo per l'interazione con l'utente; il problema è che in C queste sono le uniche funzioni fornite per la stampa e il parsing dei numeri (che, nel caso dei numeri in floating point, è un problema molto meno banale di quanto si creda), per cui molto più spesso vengono usate per la scrittura e la lettura di formati testuali ma pensati per essere letti da altri programmi (ad esempio CSV o similari), dove quello che si vuole è avere una rappresentazione testuale univoca dei dati, e non influenzata dalle impostazioni internazionali. Di conseguenza, a memoria d'uomo nessuno ha mai usato davvero il locale (specie il facet riguardante la formattazione dei numeri decimali), perché è praticamente certo che se lo si tocca si rompe qualcosa.

    Di conseguenza quello che ti dicevo sopra: stai attento a separare bene le funzioni pensate per la formattazione destinata all'utente (che devono seguire le impostazioni personalizzate) e quelle per scrittura/parsing di dati testuali ma pensati per essere machine-readable (e che quindi non devono essere influenzati dalle impostazioni custom).
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.